无法确定分配内存的正确算法
Cant determine correct algorithm to allocate memory
我有这段代码,我正在用 C 编写一个动态数组。所以这里的主要问题基本上是假设您将值 1 添加到数组,然后您决定添加值 5。好吧我的情况是,当您尝试打印假定为 1 的索引 0 时,它会给我一个段错误。但是当你打印索引 1 时,它给了我 5,这是正确的值。由于某种原因,它忘记了除一个当前值之外的所有先前添加的值。我已经完成了 valgrind 检查,我会在显示文件后显示结果:
Vertex.h:
#ifndef _VERTEX_AM_H_LB
#define _VERTEX_AM_H_LB 1
#pragma once
#include<stdint.h>
/**
* Vertex Library C
*
* GCC C99 <Vertex.h>
*
* @author Amanuel Bogale
* @copyright 2016 Amanuel Bogale
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
*/
//@union for storing
//data types supported
//for vertex
typedef union
{
char ch; //1 byte
unsigned char uch;//1 byte
signed char sch;// 1 byte
int in;//2 or 4bytes
unsigned int uin;//2 or 4bytes
long ln;// 4byte
unsigned long uln; //4byte
long long lnln; //8byte
short sh;// 2byte
unsigned short ush; //2bytes
float fl;//4byte
double db; //8byte
long double ldb; //10byte
}type;
/*
* @struct for defining
* vertex. Initalize First
*/
struct vertex_am
{
size_t current_size;
type type;
long long size_contents;
void **contents; //Array Of Void Pointers
//Add to the end of array
void (*add)(struct vertex_am *self,void*val);
};
typedef struct vertex_am vertex_am;
vertex_am* init_vertex(size_t size, vertex_am* vertex);
void end_vertex(vertex_am* vertex);
long long get_elements_num(vertex_am vert);
void add_end(vertex_am *vert, void* val);
void* get_val(vertex_am vert,long long index);
int get_first_index(vertex_am vert, void*key);
int get_last_index(vertex_am vert, void*key);
#endif
Vertex.c:
#include<stdlib.h>
#include<stdio.h>
#include<stdint.h>
#include "../includes/Vertex.h"
/**
* Vertex Library C
*
* GCC C99 <Vertex.c>
*
* @author Amanuel Bogale
* @copyright 2016 Amanuel Bogale
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
*/
vertex_am* init_vertex(size_t size, vertex_am* vertex)
{
vertex = malloc(size);
vertex->current_size = size;
vertex->size_contents = 0;
return vertex;
}
long long get_elements_num(vertex_am vert)
{
return(vert.size_contents);
}
void add_end(vertex_am *vert, void* val)
{
vert->contents = (void **)malloc(sizeof(vert->contents) + (sizeof(val)) );
// vert->contents = (void **)malloc(sizeof(void)*(vert->size_contents+1));
vert->contents[vert->size_contents] = val;
vert->size_contents++;
}
void* get_val(vertex_am vert,long long index)
{
return (vert.contents[index]);
}
int get_first_index(vertex_am vert, void*key)
{
int returner;
for(int i=0; i<=(vert.size_contents); i++)
{
if(vert.contents[i] == key)
{
returner=i;
break;
}
}
return (returner);
}
int get_last_index(vertex_am vert, void*key)
{
int returner;
for(int i=0; i<=(vert.size_contents); i++)
{
if(vert.contents[i] == key)
{
returner=i;
}
}
return (returner);
}
void end_vertex(vertex_am* vertex)
{
free(vertex);
}
main.c:
#include<stdlib.h>
#include<stdio.h>
#include<stdint.h>
#include "includes/Vertex.h"
int main()
{
int n = 34;
int x = 33;
int y = 44;
vertex_am *vert = NULL;
vert = init_vertex(sizeof(*vert), vert);
add_end(vert,&n);
add_end(vert,&x);
add_end(vert,&y);
// int *anwser = (int*) get_val(*vert, 2);
// printf("Val : %d \n",*anwser);
int *check = (int*)vert->contents[2];
printf("%d" , *check);
int first_index_anwser = get_first_index(*vert,&n);// &n same as 34. So find first 34 in dyn_array
printf("First Index : %d \n",first_index_anwser);
int last_index_anwser = get_last_index(*vert,&n);// &n same as 34. So find Last 34 dyn_array
printf("Last Index : %d \n",last_index_anwser);
end_vertex(vert);
return 0;
}
/*
* TODO POP:
* pop_beg
* pop_last
* pop_index
*
* TODO add:
* add_beg
* add_index
*
* TODO index:
* by_index instead of first last
*/
这里的问题正如你在这里看到的,我正在打印 main.c 中的当前索引:
int *check = (int*)vert->contents[2];
printf("%d" , *check);
因为如您在 main.c 中看到的那样添加了三个项目...并且第二个索引是最新的。好吧,如果我尝试打印索引 1 或 0,由于某种原因,它会出现分段错误......就像我说的,我已经为此做了一个 valgrind 检查,我得到了这个:
==37900== Memcheck, a memory error detector
==37900== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==37900== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==37900== Command: ./main
==37900==
==37900== Invalid write of size 8
==37900== at 0x4008A1: add_end (Vertex.c:34)
==37900== by 0x400747: main (main.c:17)
==37900== Address 0x5420170 is 0 bytes after a block of size 16 alloc'd
==37900== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37900== by 0x40087A: add_end (Vertex.c:32)
==37900== by 0x400747: main (main.c:17)
==37900==
==37900== Invalid read of size 8
==37900== at 0x400750: main (main.c:23)
==37900== Address 0x5420170 is 0 bytes after a block of size 16 alloc'd
==37900== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37900== by 0x40087A: add_end (Vertex.c:32)
==37900== by 0x400747: main (main.c:17)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x400900: get_first_index (Vertex.c:48)
==37900== by 0x400795: main (main.c:27)
==37900==
==37900== Invalid read of size 8
==37900== at 0x4008F9: get_first_index (Vertex.c:48)
==37900== by 0x400795: main (main.c:27)
==37900== Address 0x5420170 is 0 bytes after a block of size 16 alloc'd
==37900== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37900== by 0x40087A: add_end (Vertex.c:32)
==37900== by 0x400747: main (main.c:17)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4B43: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Use of uninitialised value of size 8
==37900== at 0x50A172B: _itoa_word (_itoa.c:179)
==37900== by 0x50A50EC: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A1735: _itoa_word (_itoa.c:179)
==37900== by 0x50A50EC: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A516F: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4C19: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A53DA: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4C6B: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4CA2: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
44First Index : 44
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x40094B: get_last_index (Vertex.c:62)
==37900== by 0x4007D7: main (main.c:30)
==37900==
==37900== Invalid read of size 8
==37900== at 0x400944: get_last_index (Vertex.c:62)
==37900== by 0x4007D7: main (main.c:30)
==37900== Address 0x5420170 is 0 bytes after a block of size 16 alloc'd
==37900== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37900== by 0x40087A: add_end (Vertex.c:32)
==37900== by 0x400747: main (main.c:17)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4B43: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Use of uninitialised value of size 8
==37900== at 0x50A172B: _itoa_word (_itoa.c:179)
==37900== by 0x50A50EC: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A1735: _itoa_word (_itoa.c:179)
==37900== by 0x50A50EC: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A516F: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4C19: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A53DA: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4C6B: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4CA2: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
Last Index : 44
==37900==
==37900== HEAP SUMMARY:
==37900== in use at exit: 48 bytes in 3 blocks
==37900== total heap usage: 5 allocs, 2 frees, 1,136 bytes allocated
==37900==
==37900== LEAK SUMMARY:
==37900== definitely lost: 48 bytes in 3 blocks
==37900== indirectly lost: 0 bytes in 0 blocks
==37900== possibly lost: 0 bytes in 0 blocks
==37900== still reachable: 0 bytes in 0 blocks
==37900== suppressed: 0 bytes in 0 blocks
==37900== Rerun with --leak-check=full to see details of leaked memory
==37900==
==37900== For counts of detected and suppressed errors, rerun with: -v
==37900== Use --track-origins=yes to see where uninitialised values come from
==37900== ERROR SUMMARY: 30 errors from 22 contexts (suppressed: 0 from 0)
amanuel@ubuntu:~/Code/E-Workspace/CustLibs$
针对 Vertex.c 中的添加函数的许多无效写入:
void add_end(vertex_am *vert, void* val)
{
vert->contents = (void **)malloc(sizeof(vert->contents) + (sizeof(val)) );
// vert->contents = (void **)malloc(sizeof(void)*(vert->size_contents+1));
vert->contents[vert->size_contents] = val;
vert->size_contents++;
}
。这是关于这个问题的所有信息,如往常一样,我们将不胜感激。
您在调用 malloc
时使用的表达式 sizeof(vert->contents) + (sizeof(val))
不会像您预期的那样工作。它会为两个指针分配space,仅此而已。无论您要为多少条目分配内存,您都只会得到 8 或 16 个字节(取决于您使用的是 32 位还是 64 位平台)。
我猜你应该分配 sizeof(*vert->contents) * (vert->size_contents+1)
字节。
还有一个问题:每次调用add_end
都会分配一块新的内存,完全忽略旧的内存,会导致内存泄漏,以及大量未初始化的内存进行上述更改后的内存。
如果你想重新分配内存,你应该使用 realloc
。如果您正确地将指针初始化为 NULL
.
,您甚至可以将其用于初始分配
所以代码应该是这样的
void **temp = realloc(vert->contents, sizeof(*vert->contents) * (vert->size_contents+1));
if (temp == NULL)
{
// TODO: Handle error
}
else
{
vert->contents = temp;
// Rest of your code...
}
在第一次调用 realloc
之前将 vert->contents
初始化为 NULL
很重要,否则您将有 未定义的行为。
我有这段代码,我正在用 C 编写一个动态数组。所以这里的主要问题基本上是假设您将值 1 添加到数组,然后您决定添加值 5。好吧我的情况是,当您尝试打印假定为 1 的索引 0 时,它会给我一个段错误。但是当你打印索引 1 时,它给了我 5,这是正确的值。由于某种原因,它忘记了除一个当前值之外的所有先前添加的值。我已经完成了 valgrind 检查,我会在显示文件后显示结果:
Vertex.h:
#ifndef _VERTEX_AM_H_LB
#define _VERTEX_AM_H_LB 1
#pragma once
#include<stdint.h>
/**
* Vertex Library C
*
* GCC C99 <Vertex.h>
*
* @author Amanuel Bogale
* @copyright 2016 Amanuel Bogale
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
*/
//@union for storing
//data types supported
//for vertex
typedef union
{
char ch; //1 byte
unsigned char uch;//1 byte
signed char sch;// 1 byte
int in;//2 or 4bytes
unsigned int uin;//2 or 4bytes
long ln;// 4byte
unsigned long uln; //4byte
long long lnln; //8byte
short sh;// 2byte
unsigned short ush; //2bytes
float fl;//4byte
double db; //8byte
long double ldb; //10byte
}type;
/*
* @struct for defining
* vertex. Initalize First
*/
struct vertex_am
{
size_t current_size;
type type;
long long size_contents;
void **contents; //Array Of Void Pointers
//Add to the end of array
void (*add)(struct vertex_am *self,void*val);
};
typedef struct vertex_am vertex_am;
vertex_am* init_vertex(size_t size, vertex_am* vertex);
void end_vertex(vertex_am* vertex);
long long get_elements_num(vertex_am vert);
void add_end(vertex_am *vert, void* val);
void* get_val(vertex_am vert,long long index);
int get_first_index(vertex_am vert, void*key);
int get_last_index(vertex_am vert, void*key);
#endif
Vertex.c:
#include<stdlib.h>
#include<stdio.h>
#include<stdint.h>
#include "../includes/Vertex.h"
/**
* Vertex Library C
*
* GCC C99 <Vertex.c>
*
* @author Amanuel Bogale
* @copyright 2016 Amanuel Bogale
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
*/
vertex_am* init_vertex(size_t size, vertex_am* vertex)
{
vertex = malloc(size);
vertex->current_size = size;
vertex->size_contents = 0;
return vertex;
}
long long get_elements_num(vertex_am vert)
{
return(vert.size_contents);
}
void add_end(vertex_am *vert, void* val)
{
vert->contents = (void **)malloc(sizeof(vert->contents) + (sizeof(val)) );
// vert->contents = (void **)malloc(sizeof(void)*(vert->size_contents+1));
vert->contents[vert->size_contents] = val;
vert->size_contents++;
}
void* get_val(vertex_am vert,long long index)
{
return (vert.contents[index]);
}
int get_first_index(vertex_am vert, void*key)
{
int returner;
for(int i=0; i<=(vert.size_contents); i++)
{
if(vert.contents[i] == key)
{
returner=i;
break;
}
}
return (returner);
}
int get_last_index(vertex_am vert, void*key)
{
int returner;
for(int i=0; i<=(vert.size_contents); i++)
{
if(vert.contents[i] == key)
{
returner=i;
}
}
return (returner);
}
void end_vertex(vertex_am* vertex)
{
free(vertex);
}
main.c:
#include<stdlib.h>
#include<stdio.h>
#include<stdint.h>
#include "includes/Vertex.h"
int main()
{
int n = 34;
int x = 33;
int y = 44;
vertex_am *vert = NULL;
vert = init_vertex(sizeof(*vert), vert);
add_end(vert,&n);
add_end(vert,&x);
add_end(vert,&y);
// int *anwser = (int*) get_val(*vert, 2);
// printf("Val : %d \n",*anwser);
int *check = (int*)vert->contents[2];
printf("%d" , *check);
int first_index_anwser = get_first_index(*vert,&n);// &n same as 34. So find first 34 in dyn_array
printf("First Index : %d \n",first_index_anwser);
int last_index_anwser = get_last_index(*vert,&n);// &n same as 34. So find Last 34 dyn_array
printf("Last Index : %d \n",last_index_anwser);
end_vertex(vert);
return 0;
}
/*
* TODO POP:
* pop_beg
* pop_last
* pop_index
*
* TODO add:
* add_beg
* add_index
*
* TODO index:
* by_index instead of first last
*/
这里的问题正如你在这里看到的,我正在打印 main.c 中的当前索引:
int *check = (int*)vert->contents[2];
printf("%d" , *check);
因为如您在 main.c 中看到的那样添加了三个项目...并且第二个索引是最新的。好吧,如果我尝试打印索引 1 或 0,由于某种原因,它会出现分段错误......就像我说的,我已经为此做了一个 valgrind 检查,我得到了这个:
==37900== Memcheck, a memory error detector
==37900== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==37900== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==37900== Command: ./main
==37900==
==37900== Invalid write of size 8
==37900== at 0x4008A1: add_end (Vertex.c:34)
==37900== by 0x400747: main (main.c:17)
==37900== Address 0x5420170 is 0 bytes after a block of size 16 alloc'd
==37900== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37900== by 0x40087A: add_end (Vertex.c:32)
==37900== by 0x400747: main (main.c:17)
==37900==
==37900== Invalid read of size 8
==37900== at 0x400750: main (main.c:23)
==37900== Address 0x5420170 is 0 bytes after a block of size 16 alloc'd
==37900== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37900== by 0x40087A: add_end (Vertex.c:32)
==37900== by 0x400747: main (main.c:17)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x400900: get_first_index (Vertex.c:48)
==37900== by 0x400795: main (main.c:27)
==37900==
==37900== Invalid read of size 8
==37900== at 0x4008F9: get_first_index (Vertex.c:48)
==37900== by 0x400795: main (main.c:27)
==37900== Address 0x5420170 is 0 bytes after a block of size 16 alloc'd
==37900== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37900== by 0x40087A: add_end (Vertex.c:32)
==37900== by 0x400747: main (main.c:17)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4B43: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Use of uninitialised value of size 8
==37900== at 0x50A172B: _itoa_word (_itoa.c:179)
==37900== by 0x50A50EC: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A1735: _itoa_word (_itoa.c:179)
==37900== by 0x50A50EC: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A516F: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4C19: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A53DA: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4C6B: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4CA2: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007B0: main (main.c:28)
==37900==
44First Index : 44
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x40094B: get_last_index (Vertex.c:62)
==37900== by 0x4007D7: main (main.c:30)
==37900==
==37900== Invalid read of size 8
==37900== at 0x400944: get_last_index (Vertex.c:62)
==37900== by 0x4007D7: main (main.c:30)
==37900== Address 0x5420170 is 0 bytes after a block of size 16 alloc'd
==37900== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==37900== by 0x40087A: add_end (Vertex.c:32)
==37900== by 0x400747: main (main.c:17)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4B43: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Use of uninitialised value of size 8
==37900== at 0x50A172B: _itoa_word (_itoa.c:179)
==37900== by 0x50A50EC: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A1735: _itoa_word (_itoa.c:179)
==37900== by 0x50A50EC: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A516F: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4C19: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A53DA: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4C6B: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
==37900== Conditional jump or move depends on uninitialised value(s)
==37900== at 0x50A4CA2: vfprintf (vfprintf.c:1631)
==37900== by 0x50AC848: printf (printf.c:33)
==37900== by 0x4007F2: main (main.c:31)
==37900==
Last Index : 44
==37900==
==37900== HEAP SUMMARY:
==37900== in use at exit: 48 bytes in 3 blocks
==37900== total heap usage: 5 allocs, 2 frees, 1,136 bytes allocated
==37900==
==37900== LEAK SUMMARY:
==37900== definitely lost: 48 bytes in 3 blocks
==37900== indirectly lost: 0 bytes in 0 blocks
==37900== possibly lost: 0 bytes in 0 blocks
==37900== still reachable: 0 bytes in 0 blocks
==37900== suppressed: 0 bytes in 0 blocks
==37900== Rerun with --leak-check=full to see details of leaked memory
==37900==
==37900== For counts of detected and suppressed errors, rerun with: -v
==37900== Use --track-origins=yes to see where uninitialised values come from
==37900== ERROR SUMMARY: 30 errors from 22 contexts (suppressed: 0 from 0)
amanuel@ubuntu:~/Code/E-Workspace/CustLibs$
针对 Vertex.c 中的添加函数的许多无效写入:
void add_end(vertex_am *vert, void* val)
{
vert->contents = (void **)malloc(sizeof(vert->contents) + (sizeof(val)) );
// vert->contents = (void **)malloc(sizeof(void)*(vert->size_contents+1));
vert->contents[vert->size_contents] = val;
vert->size_contents++;
}
。这是关于这个问题的所有信息,如往常一样,我们将不胜感激。
您在调用 malloc
时使用的表达式 sizeof(vert->contents) + (sizeof(val))
不会像您预期的那样工作。它会为两个指针分配space,仅此而已。无论您要为多少条目分配内存,您都只会得到 8 或 16 个字节(取决于您使用的是 32 位还是 64 位平台)。
我猜你应该分配 sizeof(*vert->contents) * (vert->size_contents+1)
字节。
还有一个问题:每次调用add_end
都会分配一块新的内存,完全忽略旧的内存,会导致内存泄漏,以及大量未初始化的内存进行上述更改后的内存。
如果你想重新分配内存,你应该使用 realloc
。如果您正确地将指针初始化为 NULL
.
所以代码应该是这样的
void **temp = realloc(vert->contents, sizeof(*vert->contents) * (vert->size_contents+1));
if (temp == NULL)
{
// TODO: Handle error
}
else
{
vert->contents = temp;
// Rest of your code...
}
在第一次调用 realloc
之前将 vert->contents
初始化为 NULL
很重要,否则您将有 未定义的行为。