Сравнение Char-указателя с NULL - PullRequest
2 голосов
/ 18 февраля 2011

Я использую свой код в SUSE Linux. У меня есть указатель, который я делаю = NULL в функции. Но проблема возникает, когда я пытаюсь сравнить тот же указатель с NULL в цикле while. Это приводит к сбою программы. Я воспроизвел мою проблему в примере кода ниже. Может кто-нибудь сказать, пожалуйста, что здесь происходит?

Мой код, как показано ниже:

#include <stdio.h>

int func(char *,int);

int main()
{
    char buffer[20];
    int i =20;

    int temp = func(buffer,i);

    if ( (temp == 0) && (buffer != NULL) )
    {
        printf("inside loop \n");
    }
}

int func(char *ad,int a)
{
    ad = NULL;
    printf("Integer is %d \n", a);
    return(0);
}

Проблема в том, что сравнение buffer != NULL не выполняется, и управление переходит в цикл, что не должно происходить в идеале. Я решил это, сделав это:

ad[0] = NULL, и сравнение изменилось на buffer[0] != NULL.

Поскольку NULL используется только в контексте указателя, это плохой код. Я мог бы использовать \ 0 вместо NULL в моем обходном пути и избежать написания «плохого кода», но я действительно хочу знать, что здесь происходит. Может кто-нибудь уточнить, пожалуйста?

Спасибо за тонну, Адитья

Ответы [ 2 ]

6 голосов
/ 18 февраля 2011

буфер не указатель, он не может быть NULL.

Ваш func устанавливает скопированный адрес буфера в NULL. Это никак не влияет на буфер.

РЕДАКТИРОВАТЬ: Расширенное объяснение

char buffer[20];

Это резервирует 20 байтов где-то в стеке. Они никак не инициализированы. Поскольку у вас есть 20 байтов памяти, очевидно, что эти байты должны находиться по какому-либо адресу.

int temp = func(buffer,i);

Он принимает адрес ваших 20 байтов в буфере и передает его в func.

int func( char *ad,int a)
{

ad = NULL;

Здесь у вас на новой позиции в стеке новая переменная-указатель, которая будет существовать только во время выполнения func. Эта переменная-указатель имеет адрес , а указывает на адрес . Вы изменяете этот указатель, который влияет на то, куда он указывает. Но это никак не изменит ваш исходный буфер, поскольку ad - это только временная переменная в стеке, которая содержит адрес байтов в вашей переменной buffer (пока вы не установите для этой временной переменной значение NULL).

4 голосов
/ 18 февраля 2011

Две проблемы:

  1. В func вы пытаетесь изменить значение ad, , а не , на что указывает ad. Это не будет работать, так как изменения значения параметра не отражаются в вызывающей программе. Вам нужно изменить этот код на

    
    int func(char **ad, int a)
    {
      *ad = NULL;
      printf("Integer is %d\n", a);
      return 0;
    }
    
    
    К сожалению, это не будет работать с остальным кодом, так как ...
  2. buffer объявлен как объект массива, а не как указатель, и вы не можете изменить объект массива; IOW, buffer не может быть назначен. Не говоря уже о том, что тип &buffer является char (*)[20], а не char **.

Вот модифицированная версия вашего источника, которая будет «работать», хотя я не уверен, чего вы пытаетесь достичь:

#include <stdio.h>
#include <stdlib.h>

#define SIZE 20

int func(char **ad, int a)
{
  *ad = NULL;                   // WOOPA! WOOPA! MEMORY LEAK!!! MEMORY LEAK!!!
  printf("Integer is %d\n", a);
  return 0;
}

int main(void)
{
  char *buffer = malloc(sizeof *buffer * SIZE);
  int i = 20;
  int temp = func(&buffer, i);
  if (temp == 0 && buffer != NULL)
    printf("Inside loop\n");
  return 0;
}
...