1

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

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,直到这里检查,并修复了潜在的缓冲区溢出(他忘记在 insert->numBin 中复制 NULL 终止符)。

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

有任何想法吗?建议?可能的驱魔技术?(当前的黑客正在将 sig 指针复制到一个临时变量并在 malloc 之后恢复它。无论如何它都会中断。结果第二个 malloc 也破坏了它。有趣的是,它将 sig 重置为与第一个完全相同的值)。

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

4

3 回答 3

1

一个问题是这一行:

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

它应该是

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

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

您需要为 Node 结构分配空间,而不是为指向 Node 结构的指针分配空间(顺便说一下,在 32 位系统上将是 4 个字节)

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

于 2010-04-26T03:21:09.447 回答
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];

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

insert->numBin = strdup(auxBin);

编辑:刚刚注意到您在 Windows 上,因此 strdup() 可能不可用(这是一个 POSIX 例程),因此您可以通过这种方式覆盖字符串重复。请注意终止符长度上的 +1:

insert->numBin = (char *)malloc( strlen(auxBin)+1 );
strcpy( insert->numBin, auxBin );
于 2010-04-26T03:23:47.877 回答
0

当您为字符串 (char *) 分配内存时,请确保它的长度为 strlen + 1,用于结尾的 \0。

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

需要是

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

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

John 关于如何分配结构的另一件事是正确的,它不能是指针的大小,而是结构的大小。

于 2010-04-26T03:21:39.613 回答