无法在使用 strdup 的图形的 C 实现中释放内存
Unable to free memory in my C implementation of graph which uses strdup
下面是我的图的数据结构:
typedef struct EdgeNode{
int adjvex;
struct EdgeNode *nextarc;
}ENode;
typedef struct VertexNode{
char *data;
char *gcc;
int multi_gcc;
int is_target;
ENode *firstarc;
}VNode;
typedef struct MyGraph{
VNode vertices[100];
}Graph;
然后我先把所有顶点的gcc字段初始化为NULL:
if (get_pos(*pGraph, target[j],i) == -1 && target[j][0] != '\n' && target[j][0] != '[=11=]'){
pGraph->vertices[i].data = malloc(strlen(target[j])+1);
strcpy(pGraph->vertices[i].data, target[j]);
pGraph->vertices[i].gcc = NULL;
if (j == 0)
pGraph->vertices[i].is_target = 1;
else{
pGraph->vertices[i].is_target = 0;
}
pGraph->vertices[i].firstarc = NULL;
pGraph->vertices[i].multi_gcc = 0;
i++;
}
对于图中的某些特定顶点,我将 gcc 字段更改为其他字符串:
else{
new_command = 1;
int tmp;
tmp = get_pos(*pGraph,my_target,i);
char* storage = (char *)malloc(sizeof(char)*need);
char* real_gcc = (char *)malloc(sizeof(char)*need);
strcpy(storage,target[0]);
for(j = 1; j < target_id; ++j) {
strcat(storage, " " );
strcat(storage, target[j]);
}
if (new_command){
if (pGraph -> vertices[tmp].gcc == NULL){
pGraph->vertices[tmp].gcc = strdup(storage); //valgrind error
}else{
printf("the gcc is %s\n",pGraph->vertices[tmp].gcc);
strcpy(real_gcc,pGraph->vertices[tmp].gcc);
strcat(real_gcc,"*");
strcat(real_gcc,storage);
pGraph->vertices[tmp].gcc = strdup(real_gcc); //valgrind error
if (pGraph->vertices[tmp].multi_gcc == 0){
pGraph->vertices[tmp].multi_gcc = 1;
}
}
}
free(storage);
free(real_gcc);
}
valgrind 给出这样的消息,发生在我之前在代码段上标记 "valgrind error" 的地方:
==1674== 28 bytes in 1 blocks are definitely lost in loss record 1 of 2
==1674== at 0x4C2AB80: malloc (in *)
==1674== by 0x4EBFB49: strdup (strdup.c:42)
==1674== by 0x402343: main (mymake.c:456)
==1674==
==1674== 56 bytes in 1 blocks are definitely lost in loss record 2 of 2
==1674== at 0x4C2AB80: malloc (in *)
==1674== by 0x4EBFB49: strdup (strdup.c:42)
==1674== by 0x402422: main (mymake.c:466)
我只是不明白内存泄漏的原因,看起来它只发生在最后一个顶点上。有帮助吗?
您正在泄漏内存,因为您正在覆盖指向 malloc 内存的指针:
if (pGraph -> vertices[tmp].gcc == NULL){
pGraph->vertices[tmp].gcc = strdup(storage);
}else{
// pGraph->vertices[tmp].gcc points to a valid memory location
printf("the gcc is %s\n",pGraph->vertices[tmp].gcc);
strcpy(real_gcc,pGraph->vertices[tmp].gcc);
strcat(real_gcc,"*");
strcat(real_gcc,storage);
// ** pGraph->vertices[tmp].gcc is overwritten **
pGraph->vertices[tmp].gcc = strdup(real_gcc);
if (pGraph->vertices[tmp].multi_gcc == 0){
pGraph->vertices[tmp].multi_gcc = 1;
}
你需要free
内存才能给这个指针赋新值。
printf("the gcc is %s\n",pGraph->vertices[tmp].gcc);
strcpy(real_gcc,pGraph->vertices[tmp].gcc);
strcat(real_gcc,"*");
strcat(real_gcc,storage);
free(pGraph->vertices[tmp].gcc);
pGraph->vertices[tmp].gcc = strdup(real_gcc);
下面是我的图的数据结构:
typedef struct EdgeNode{
int adjvex;
struct EdgeNode *nextarc;
}ENode;
typedef struct VertexNode{
char *data;
char *gcc;
int multi_gcc;
int is_target;
ENode *firstarc;
}VNode;
typedef struct MyGraph{
VNode vertices[100];
}Graph;
然后我先把所有顶点的gcc字段初始化为NULL:
if (get_pos(*pGraph, target[j],i) == -1 && target[j][0] != '\n' && target[j][0] != '[=11=]'){
pGraph->vertices[i].data = malloc(strlen(target[j])+1);
strcpy(pGraph->vertices[i].data, target[j]);
pGraph->vertices[i].gcc = NULL;
if (j == 0)
pGraph->vertices[i].is_target = 1;
else{
pGraph->vertices[i].is_target = 0;
}
pGraph->vertices[i].firstarc = NULL;
pGraph->vertices[i].multi_gcc = 0;
i++;
}
对于图中的某些特定顶点,我将 gcc 字段更改为其他字符串:
else{
new_command = 1;
int tmp;
tmp = get_pos(*pGraph,my_target,i);
char* storage = (char *)malloc(sizeof(char)*need);
char* real_gcc = (char *)malloc(sizeof(char)*need);
strcpy(storage,target[0]);
for(j = 1; j < target_id; ++j) {
strcat(storage, " " );
strcat(storage, target[j]);
}
if (new_command){
if (pGraph -> vertices[tmp].gcc == NULL){
pGraph->vertices[tmp].gcc = strdup(storage); //valgrind error
}else{
printf("the gcc is %s\n",pGraph->vertices[tmp].gcc);
strcpy(real_gcc,pGraph->vertices[tmp].gcc);
strcat(real_gcc,"*");
strcat(real_gcc,storage);
pGraph->vertices[tmp].gcc = strdup(real_gcc); //valgrind error
if (pGraph->vertices[tmp].multi_gcc == 0){
pGraph->vertices[tmp].multi_gcc = 1;
}
}
}
free(storage);
free(real_gcc);
}
valgrind 给出这样的消息,发生在我之前在代码段上标记 "valgrind error" 的地方:
==1674== 28 bytes in 1 blocks are definitely lost in loss record 1 of 2
==1674== at 0x4C2AB80: malloc (in *)
==1674== by 0x4EBFB49: strdup (strdup.c:42)
==1674== by 0x402343: main (mymake.c:456)
==1674==
==1674== 56 bytes in 1 blocks are definitely lost in loss record 2 of 2
==1674== at 0x4C2AB80: malloc (in *)
==1674== by 0x4EBFB49: strdup (strdup.c:42)
==1674== by 0x402422: main (mymake.c:466)
我只是不明白内存泄漏的原因,看起来它只发生在最后一个顶点上。有帮助吗?
您正在泄漏内存,因为您正在覆盖指向 malloc 内存的指针:
if (pGraph -> vertices[tmp].gcc == NULL){
pGraph->vertices[tmp].gcc = strdup(storage);
}else{
// pGraph->vertices[tmp].gcc points to a valid memory location
printf("the gcc is %s\n",pGraph->vertices[tmp].gcc);
strcpy(real_gcc,pGraph->vertices[tmp].gcc);
strcat(real_gcc,"*");
strcat(real_gcc,storage);
// ** pGraph->vertices[tmp].gcc is overwritten **
pGraph->vertices[tmp].gcc = strdup(real_gcc);
if (pGraph->vertices[tmp].multi_gcc == 0){
pGraph->vertices[tmp].multi_gcc = 1;
}
你需要free
内存才能给这个指针赋新值。
printf("the gcc is %s\n",pGraph->vertices[tmp].gcc);
strcpy(real_gcc,pGraph->vertices[tmp].gcc);
strcat(real_gcc,"*");
strcat(real_gcc,storage);
free(pGraph->vertices[tmp].gcc);
pGraph->vertices[tmp].gcc = strdup(real_gcc);