【发布时间】:2016-05-16 07:10:55
【问题描述】:
我的结构如下所示:
struct tree{
char *name;
int num_subdirs;
struct tree **subdirs;
}
我正在接收一个缓冲区,其中包含在缓冲区中序列化的整个树。我试图在这个函数中反序列化它:
struct tree *t;
//buffer is filled, received from somewhere else.
int res = deserialize(t, buf); //call function deserialize
//deserialize function
//buf = {../,2}{sd,0}{|}{sr,1}{sk,0}{|}{|}
│406 int dfsDeserialize(struct tree *dt, void *buf, int *q){ │
│407 char name[MAXPATHLEN]; │
│408 char delim[3]; │
│409 int len, numsubs, i; │
│
│411 sscanf(buf+(*q),"%3s",delim); │
│412 if(!strcmp(delim,"{|}")){ │
│413 (*q)+=3; │
│414 return 1; │
│415 } │
│416 sscanf((buf + (*q)), "{%[^,],%d}%n", name, &numsubs, &len); │ │
>│419 int slen = strlen(name); │
│420 dt->name = calloc(slen + 1, 1); │
│421 dt->subdirs = malloc(numsubs*sizeof(struct tree *)); │
│422 strcpy(dt->name, name); │
│423 dt->num_subdirs = numsubs; │
│424 (*q)+=len; │
│425 for(i = 0; i< numsubs; i++){ │
│426 dt->subdirs[i] = malloc(sizeof(struct tree)); │
│427 dfsDeserialize(dt->subdirs[i], buf, q); │
│428 } │
│429 return 0; │
│430 }
│
我尝试了几种不同的为字符串分配内存的方法,但每次都失败!我不知道为什么 t->name 总是 0x0。请帮忙。
【问题讨论】:
-
你是如何将
t传递给函数dfsDeserialize的? -
我声明了一个 t 并通过了它。即结构树 *t;
-
由于您跳过了解析缓冲区的代码并且我们可以看到的代码看起来没问题,我们不得不假设您省略的代码导致了问题 - 或者您在其他地方有一些内存问题这最终在这里引发了一个问题。您是否在可以使用
valgrind的平台上?如果是这样,请使用它。如果没有,生活会更艰难。 -
请注意,
t就像一个局部变量,离开函数后它所指向的内容将会丢失。如果要永久更改t指向的内容,则需要传递t的地址 -
你有一个缓冲区溢出。格式字符串的大小为
%3s,但数组只有 3 个字节长。不幸的是,scanf()函数的大小不包括空终止符,因此您有可能覆盖一个字节,这可能是灾难性的。将delim的大小至少增加到 4,或者将格式更改为指定 2 而不是 3。这是否是您所有麻烦的原因还有待商榷,但缓冲区溢出绝不是好消息。