我正在帮助一位朋友调试他的程序,其中包括链接列表。他的列表结构非常简单:
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'
)
答案 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对于如何分配结构是正确的,它不能是指针的大小而是结构的大小。