2016-05-11 5 views
0

После запуска Valgrind на моем коде я получил сообщение об ошибке:Неинициализированное значение было создано распределением кучи. Зачем?

uninitialized value was created by a heap allocation. 

Мой код:

void adicionaHashtag(char* x){ 
    char*y=malloc(sizeof(x));/***ERROR IS HERE***/ 
    int i; 
    for(i=0; i<strlen(x); i++){ 
     y[i]=tolower(x[i]); 
    } 

    Lista_Hashtags*aux = (Lista_Hashtags*)malloc(sizeof(Lista_Hashtags)); 
    strcpy(aux->nome, y); 
    aux->contador=1; 
    if(contador_unitario == 0){ 
     ultimo = aux; 
    } 
    contador_unitario++; 
    aux->proximo = primeiro; 
    primeiro = aux; 
} 

какие-либо советы?

также, что означает «условный переход или перемещение зависит от неинициализированного значения (значений)» означает? ~

+7

Использование 'SizeOf (х)' неверен там. Выделите память равной 'strlen (x) + 1'' 'y'. – ameyCU

+2

Кроме того, не забудьте добавить '\ 0' в' y' или 'strcpy', будут проблемы. –

+0

извините заранее за вопрос «нуб». Как я должен добавить \ 0 в y? strcpy действительно дает проблемы. @Johny Mopp –

ответ

1

"неинициализированным значение ..." Вы можете использовать char*y=calloc(strlen(x),0); вместо char*y=malloc(sizeof(x)); .Initialize памяти с "0".

+0

Или вы можете инициализировать память после ее выделения. All-bits-zero может быть или не быть допустимым начальным значением. Например, нулевые указатели обычно представляются как все-бит-ноль, но на самом деле это не гарантируется. –

+2

размер нужен +1 для нулевого терминатора –

+0

@KeithThompson все биты нуль действительны для 'char', поскольку он является целым типом –

0
void adicionaHashtag(char* x){ 
    char*y=malloc(sizeof(x));/***ERROR IS HERE***/ 
    int i; 
    for(i=0; i<strlen(x); i++){ 
     y[i]=tolower(x[i]); 
    } 

Вы пытаетесь выделить и инициализировать строку с копией строки, на которую указывает x.

sizeof(x) - размер указателя char*. Обычно это 4 или 8 байтов. Вы должны выделить достаточно места для хранения самой строки.

char *y = malloc(strlen(x) + 1); 

+ 1 является возможность для завершающего нулевого символа '\0'.

Вызов strlen на каждой итерации цикла неэффективен, но не является неправильным; Сейчас я оставлю это. . Там есть потенциальная проблема, если какой-либо из скопированных символов имеют отрицательные значения (неудачную характеристику функции tolower() Назначение должно быть:

y[i] = tolower((unsigned char)x[i]); 

Наконец, скажем x указывает на строку "hello" Вы правильно копируя. 5 символов -., но не окончательный '\0' Одним из возможных решений является изменение < в состоянии петлевой <=, который будет копировать символы от 0 до 5, а не от 0 до 4.

Но вы можете просто использовать существующий strcpy функция, которая обрабатывает все это для вас (И более эффективно):

char *y = malloc(strlen(x) + 1); 
strcpy(y, x); 

(. Вы должны также проверить значение, возвращаемое malloc, и относиться к нему как ошибка, если это NULL)

по этому вопросу, вы, вероятно, не нужно y вообще. x уже является указателем на строку. Скопируйте его в память, выделенную для y, а затем скопируйте ее в aux->nome. Если нет кода, который вы нам не показали, который использует y, это не нужно (и утечка памяти!). Вы можете оставить декларацию y и код, который инициализирует его и просто скопировать из x непосредственно:

Lista_Hashtags *aux = malloc(sizeof *aux); 
strcpy(aux->nome, x); 

(Это предполагает, что aux->nome является массивом, а не указатель, и что это достаточно большой, чтобы держать копию строки.)

(Обратите внимание, что я изменил свой malloc призыв к более простой и надежной форме.)

+0

@MichaelBurr: Обратите внимание, что 'strdup' является нестандартным. –