未初始化的值是由堆分配创建的。为什么?
uninitialized value was created by a heap allocation. why?
在我的代码上使用 运行 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;
}
有什么建议吗?
还有,"Conditional jump or move depends on uninitialised value(s)"是什么意思?
~
"uninitialized value ..."
您可以使用 char*y=calloc(strlen(x),0);
而不是 char*y=malloc(sizeof(x));
。用“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 个字节。您需要分配足够的 space 来保存字符串本身。
char *y = malloc(strlen(x) + 1);
+ 1
允许终止空字符 '[=19=]'
。
在循环的每次迭代中调用 strlen
是低效的,但并非不正确;我暂时不说了。如果任何复制的字符具有负值(tolower()
函数的一个不幸特征。赋值应该是:
y[i] = tolower((unsigned char)x[i]);
最后,假设x
指向字符串"hello"
。您正确地复制了 5 个字符——但不是最后的 '[=19=]'
。一种可能的修复方法是将循环条件中的 <
更改为 <=
,这将复制字符 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
调用更改为更简单、更可靠的形式。)
在我的代码上使用 运行 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;
}
有什么建议吗?
还有,"Conditional jump or move depends on uninitialised value(s)"是什么意思? ~
"uninitialized value ..."
您可以使用 char*y=calloc(strlen(x),0);
而不是 char*y=malloc(sizeof(x));
。用“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 个字节。您需要分配足够的 space 来保存字符串本身。
char *y = malloc(strlen(x) + 1);
+ 1
允许终止空字符 '[=19=]'
。
在循环的每次迭代中调用 strlen
是低效的,但并非不正确;我暂时不说了。如果任何复制的字符具有负值(tolower()
函数的一个不幸特征。赋值应该是:
y[i] = tolower((unsigned char)x[i]);
最后,假设x
指向字符串"hello"
。您正确地复制了 5 个字符——但不是最后的 '[=19=]'
。一种可能的修复方法是将循环条件中的 <
更改为 <=
,这将复制字符 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
调用更改为更简单、更可靠的形式。)