Malloc在C中破坏了malloc的内存

时间:2010-04-26 03:17:13

标签: c memory-management corruption

我正在帮助一位朋友调试他的程序,其中包括链接列表。他的列表结构非常简单:

typedef struct nodo{
    int cantUnos;
    char* numBin;
    struct nodo* sig;
}Nodo;

我们有以下代码段:

void insNodo(Nodo** lista, char* auxBin, int auxCantUnos){
   printf("*******Insertando\n");
int i;
   if (*lista) printf("DecInt*%p->%p\n", *lista, (*lista)->sig);
Nodo* insert = (Nodo*)malloc(sizeof(Nodo*));
   if (*lista) printf("Malloc*%p->%p\n", *lista, (*lista)->sig);
insert->cantUnos = auxCantUnos;
insert->numBin = (char*)malloc(strlen(auxBin)*sizeof(char));
for(i=0 ; i<strlen(auxBin) ; i++)
    insert->numBin[i] = auxBin[i];
insert->numBin[i] = '\0';
insert->sig = NULL;
Nodo* aux;
/* [etc] */

(带有额外缩进的行是我出于调试目的添加的)

这让我得到以下结论:

*******Insertando
DecInt*00341098->00000000
Malloc*00341098->2832B6EE

(*lista)->sig以前和故意设置为NULL,直到此处检出,并修复了潜在的缓冲区溢出(他忘记复制插入中的NULL终结符 - > numBin)

我想不出为什么会发生这种情况的原因,我也不知道我还应该提供什么作为进一步的信息。 (在完全修补的Windows 7下编译最新稳定的MinGW,朋友在Windows XP下使用MinGW。在我的机器上,至少,只有 在没有连接GDB时发生。)

有什么想法吗?建议?可能的驱魔技术? (当前hack正在将sig指针复制到temp变量并在malloc之后将其恢复。它无论如何都会中断。原来第二个malloc也会破坏它。有趣的是,它会将sig重置为与第一个完全相同的值。) p>

更新:感谢您的回答。关于Node*事,它是固定的,但没有变化。至少可以防止之后的潜在问题。字符串复制不是问题,因为我已经自己修复了所有丢失的\ 0。 (注意for之后的insertBin[i] = '\0'

3 个答案:

答案 0 :(得分:1)

这一行存在一个问题:

Nodo* insert = (Nodo*)malloc(sizeof(Nodo*)); 

应该是

Nodo* insert = (Nodo*)malloc(sizeof(Nodo)); 

(经验法则:你应该在sizeof()中少一个'*')

您需要为Node结构分配空间, NOT 空间用于指向Node结构的指针(在32位系统上,这将是4个字节)

存在一个类似的问题,即没有为字符串分配足够的空间(char数组);不要忘记终止零'\ 0'

的空间

答案 1 :(得分:1)

在这一行:

Nodo* insert = (Nodo*)malloc(sizeof(Nodo*));

你只为指向Nodo的指针分配足够的内存,而不是整个Nodo。你想要:

Nodo* insert = (Nodo*)malloc(sizeof(Nodo));

此外,您可能至少还有一个其他分配错误:

insert->numBin = (char*)malloc(strlen(auxBin)*sizeof(char));
for(i=0 ; i<strlen(auxBin) ; i++)
    insert->numBin[i] = auxBin[i];

看起来你正在重复一个字符串。您需要为字符串加上一个足够的分配来获得终止\0。您可以使用此标准库调用进行简化:

insert->numBin = strdup(auxBin);
编辑:刚刚注意到你在Windows上,所以strdup()可能不可用(这是一个POSIX例程)所以你可以用这种方式覆盖字符串重复。注意终止符的长度为+1:

insert->numBin = (char *)malloc( strlen(auxBin)+1 );
strcpy( insert->numBin, auxBin );

答案 2 :(得分:0)

为字符串(char *)分配内存时,请确保最后为\ 0的长度为strlen + 1。

insert->numBin = (char*)malloc(strlen(auxBin)*sizeof(char));

需要

insert->numBin = (char*)malloc(strlen(auxBin) + 1);

也没有必要说* sizeof(char)是1。

John对于如何分配结构是正确的,它不能是指针的大小而是结构的大小。