我有一个结构,除其他外,必须包含动态创建的字符串和动态创建的字符串数组。但是,我发现之后很难释放这个结构,因为它给了我运行时错误。
所以问题是:
到目前为止,我甚至无法释放字符串。为什么呢?
如何在此结构中创建字符串的动态“数组”?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct {
unsigned int num;
unsigned int* sizes;
unsigned int* coords;
char* name;
} TOPOLOGY;
TOPOLOGY * constructor() {
char * name="Hardware Topology";
TOPOLOGY * top=calloc(1,sizeof(TOPOLOGY *));
top->num=0;
top->name=calloc(1,strlen(name));
strcpy(top->name,name);
return top;
}
void destructor(TOPOLOGY * top) {
if(top->sizes!=NULL) { free(top->sizes); }
if(top->coords!=NULL) { free(top->coords); }
if(top->name!=NULL) { free(top->name); } exit(0);
if(top!=NULL) { free(top); }
}
void add(TOPOLOGY * top, unsigned int size) {
top->num++;
size_t s=top->num*sizeof(unsigned int*);
top->sizes=realloc(top->sizes,s);
top->coords=realloc(top->coords,s);
top->sizes[top->num-1]=size;
}
void coords(TOPOLOGY * top, unsigned int coords[]) {
int i;
for(i=0;i<top->num;i++) {
top->coords[i]=coords[i];
}
}
void get(TOPOLOGY * top) {
int i;
for(i=0; i<top->num;i++) {
printf("Dim: %d: %d\n",i,top->sizes[i]);
}
}
void getcoords(TOPOLOGY * top) {
int i;
for(i=0;i<top->num;i++) {
printf("Coord %d = %d\n",i,top->coords[i]);
}
}
void setname(TOPOLOGY * top, char * name) {
int s=sizeof(name);
top->name=realloc(top->name,s);
strcpy(top->name,name);
}
int main() {
unsigned int c[4]={3,2,0,1};
TOPOLOGY * top=constructor();
add(top,1025);
add(top,512);
add(top,10);
add(top,24);
coords(top,c);
get(top);
getcoords(top);
destructor(top);
return 0;
}
答案 0 :(得分:2)
首先,构造函数是错误的。它将为您提供计算机上指针的大小,因此非常从那时起您使用top
所做的一切都将是非法的。
TOPOLOGY * top=calloc(1,sizeof(TOPOLOGY *)); /* Wrong. */
^
top = calloc(1, sizeof(TOPOLOGY)); /* Better. */
top = calloc(1, sizeof(*top)); /* Even better. */
在calloc
字符串的任何地方,您必须使用strlen(...) + 1
。
top->name=calloc(1, strlen(name) + 1);
strcpy(top->name, name);
或稍微横向使用strdup
:
top->name = strdup(name); /* Does malloc and whatnot for you. */
释放时不要检查NULL
。这对free(NULL)
完全合法。
void destructor(TOPOLOGY * top)
{
free(top->sizes);
free(top->coords);
free(top->name);
free(top);
}
答案 1 :(得分:0)
有两件事让人想起:
top->name=calloc(1,strlen(name));
在这里,您应该为空终止符分配一个字节,或者在调用strcpy
时创建一个未终止的字符串。 (此外,name
中的本地constructor()
应声明为const char *
。)
if(top->coords!=NULL) { free(top->coords); }
您永远不会将coords
初始化为零。因此,如果您只是在新建的结构上调用destructor
,那么您很可能会调用无效的free()
。