C 如何从包含动态创建字符串数组的结构中释放内存?
我有一个结构,其中必须包含一个动态创建的字符串和一个动态创建的字符串数组。然而,我发现以后很难释放这个结构,因为它会给我运行时错误 因此,问题是: 到目前为止,我甚至无法释放字符串。为什么? 如何在此结构中创建字符串的动态“数组”C 如何从包含动态创建字符串数组的结构中释放内存?,c,data-structures,struct,cstring,C,Data Structures,Struct,Cstring,我有一个结构,其中必须包含一个动态创建的字符串和一个动态创建的字符串数组。然而,我发现以后很难释放这个结构,因为它会给我运行时错误 因此,问题是: 到目前为止,我甚至无法释放字符串。为什么? 如何在此结构中创建字符串的动态“数组” #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> typedef struct { unsigned i
#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;
}
#包括
#包括
#包括
#包括
类型定义结构{
无符号整数;
无符号整数*大小;
无符号整数*坐标;
字符*名称;
}拓扑结构;
拓扑*构造函数(){
char*name=“硬件拓扑”;
拓扑*top=calloc(1,sizeof(拓扑*);
top->num=0;
top->name=calloc(1,strlen(name));
strcpy(顶部->名称,名称);
返回顶部;
}
无效析构函数(拓扑*顶部){
如果(顶部->大小!=NULL){free(顶部->大小);}
如果(top->coords!=NULL){free(top->coords);}
如果(top->name!=NULL){free(top->name);}退出(0);
如果(top!=NULL){free(top);}
}
void add(拓扑*top,无符号整数大小){
top->num++;
size_t s=top->num*sizeof(unsigned int*);
顶部->尺寸=realloc(顶部->尺寸,s);
顶部->坐标=realloc(顶部->坐标,s);
顶部->尺寸[顶部->数值-1]=尺寸;
}
无效坐标(拓扑*顶部,无符号整数坐标[]){
int i;
对于(i=0;inum;i++){
top->coords[i]=coords[i];
}
}
void get(拓扑*顶部){
int i;
对于(i=0;inum;i++){
printf(“尺寸:%d:%d\n”,i,顶部->尺寸[i]);
}
}
void getcoords(拓扑*顶部){
int i;
对于(i=0;inum;i++){
printf(“坐标%d=%d\n”,i,top->coords[i]);
}
}
void setname(拓扑*顶部,字符*名称){
int s=sizeof(名称);
top->name=realloc(top->name,s);
strcpy(顶部->名称,名称);
}
int main(){
无符号int c[4]={3,2,0,1};
拓扑*top=constructor();
增加(顶部,1025);
添加(顶部,512);
增加(前10名);
增加(顶部,24);
coords(顶部,c);
得到(顶部);
getcoords(顶部);
析构函数(顶部);
返回0;
}
想到两件事:
top->name=calloc(1,strlen(name))
这里您应该为空终止符多分配一个字节,否则在调用strcpy
时将创建一个未终止的字符串。(另外,constructor()
中的本地name
应声明为const char*
)如果(top->coords!=NULL){free(top->coords);}
您永远不会将coords
初始化为零。因此,如果您只是在一个新创建的结构上调用析构函数
,那么很可能是在调用一个无效的free()
首先,构造函数是错误的。它将为您提供计算机上指针的大小,因此从那时起,您使用
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
。免费(空)
是完全合法的
@我当然是。你也是;如果你不相信我,试试看。
void destructor(TOPOLOGY * top)
{
free(top->sizes);
free(top->coords);
free(top->name);
free(top);
}