Сравнение указателя Char с NULL

Я запускаю свой код в 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 в моем обходном пути и избежать написания "плохого кода", но я действительно хочу знать, что здесь происходит. Может кто-нибудь уточнить?

Большое спасибо, Адитья


person Aditya    schedule 18.02.2011    source источник
comment
Здесь нет петли. О какой петле вы говорите?   -  person Artefacto    schedule 18.02.2011
comment
NULL используется для сравнения с указателями. Его макрос заменяется на константу нулевого указателя. Так что buffer[0] != NULL неверно, потому что buffer[0] относится к типу данных char.   -  person Mahesh    schedule 18.02.2011


Ответы (2)


буфер не является указателем, он не может быть 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).

person Erik    schedule 18.02.2011
comment
Спасибо! Теперь понял, отличное объяснение. Спасибо еще раз за помощь. - person Aditya; 20.02.2011

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

  1. In func, you're attempting to modify the value of ad, not what ad points to. This won't work, as changes to the parameter value are not reflected in the caller. You would need to change that code to

    
    int func(char **ad, int a)
    {
      *ad = NULL;
      printf("Integer is %d\n", a);
      return 0;
    }
    
    
    Unfortunately, this won't work with the rest of the code, since...

  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;
}
person John Bode    schedule 18.02.2011
comment
То, что я пытался сделать, это прочитать запись файла за записью, используя fgets. После последней записи я хотел сделать буфер NULL и сравнить его в звонилке. Этого не происходило, и, следовательно, произошел сбой. - person Aditya; 20.02.2011
comment
Спасибо за помощь! Действительно ценится. - person Aditya; 20.02.2011