2012-01-07 71 views
0

我需要在我的程序中的一堆不同位置分配结构数组,从而将这些工作放入一个函数(VS 2010)中。编译器给出了有关使用未初始化变量的警告。那么我该如何传递它,以及如何在函数中声明它。我已经尝试了很多“&”和“*”的变体,但都无济于事。在函数内部传递指针用于内存分配?

(我提前道歉,如果我的代码导致的任何形式的恶心......我是英语专业。)

struct s_stream { 
int blah; 
}; 

void xxyz(void) 
{ 
    struct s_stream **StreamBuild; 
    char *memBlock_1; 

    xalloc(StreamBuild, memBlock_1, 20); 
} 



void xalloc(struct s_stream **StreamStruct, char *memBlock, int structCount) 
{ 
    int i = sizeof(struct s_stream *); 
    if ((StreamStruct=(struct s_stream **) malloc(structCount * i)) == NULL) 
     fatal("failed struct pointer alloc"); 

    int blockSize = structCount * sizeof(struct s_stream); 
    if ((memBlock = (char *) malloc(blockSize)) == NULL) 
     fatal("failed struct memBlock alloc"); 

    // initialize all structure elements to 0 (including booleans) 
    memset(memBlock, 0, blockSize); 

    for (int i = 0; i < structCount; ++i) 
     StreamStruct[i]=(struct s_stream *) &memBlock[i*sizeof(struct s_stream) ]; 
} 
+0

你到底想要做什么 - 是否动态分配'struct s_stream'对象的数组? – 2012-01-07 20:10:03

+0

告诉我们编译器的确切警告。特别是编译器不喜欢哪一行代码? – 2012-01-07 23:58:47

回答

0

你传入指针memBlock_1副本xalloc,所以通过malloc返回的地址被写入复制和永远不会到达调用函数。既然你大概想的地址提供给xxyzmemBlock_1,你必须通过一个指针到指针到焦炭作为第二个参数,

void xalloc(..., char **memBlock, ...) 

xalloc(..., &memBlock_1, ...);调用它。在xalloc的主体中,将所有出现的memBlock替换为*memblock,例如, (*memblock = malloc(blockSize)) == NULL(不需要投)。

类似地,的xallocStreamStruct的参数从不改变在xxyzStreamBuild指针到指针到结构s_stream。如果我正确解释你的意图,你还必须添加一个指向该参数的指针层,void xalloc(struct s_stream ***StreamStruct, ..., ...),在调用中传递StreamBuild的地址,xalloc(&StreamBuild, ..., ...)并取消引用函数体中的指针,例如, (*StreamStruct = malloc(structCount * i)) == NULL

+0

我遵循你的建议;剩下的2个问题:编译器将不允许:(* StreamStruct = malloc(structCount * i))...我必须转换为(struct s_stream **)。另一个问题是我通过循环并将指针指向内存块的最后2行:for(int i = 0; i PaeneInsula 2012-01-07 21:56:23

+0

如果您需要投射'malloc'的结果,那意味着您将程序编译为C++,而不是C。可能不是什么大不了的事情,这两个人有足够的共同点,那就是简单的程序编译和工作都是这样的(在投射'malloc'返回等等之后)。在循环中,它应该是'for(...)(* StreamStruct)[i] =&memBlock [...];' - 除非我忽略了某些东西。嗯,'未处理的异常'。是的,C++。如果你正在编译为C++(对于微软的编译器来说不是一个坏主意,它不支持C99,但它可以作为C++编译器),你可以考虑使用'new'等编写C++。 – 2012-01-07 22:14:06

+0

这是正确的? for(...)(* StreamStruct)[i] =&memBlock [...]; OR(...)(* StreamStruct)[i] =(* memBlock)[...]; ?后者似乎工作,并与前面说的一致... – PaeneInsula 2012-01-07 23:41:31

3

我不太确定我明白你的问题,但它似乎像你需要一个函数来创建一个动态分配的struct s_stream对象数组并将它们返回给调用者。如果是这样的话,这是很容易:

void easiest(void) 
{ 
    struct s_stream *array = malloc(20 * sizeof(struct s_stream)); 
} 

您可以在malloc()关闭移动到其自身的功能和返回指针:

void caller(void) 
{ 
    struct s_stream *array = create_array(20); 
} 

struct s_stream *create_array(int count) 
{ 
    return malloc(count * sizeof(struct s_stream)); 
} 

或者,如果你坚持要传递数组作为参数:

void caller(void) 
{ 
    struct s_stream *array; 
    create_array(&array, 20); 
} 

void create_array(struct s_stream **array, int count) 
{ 
    *array = malloc(count * sizeof(struct s_stream)); 
} 
+0

你的第一个'create_array()'应该返回'void *'不应该吗?或者更好'struct stream *'是类型安全的。 – alk 2012-01-07 20:41:42

+0

Yup - 打印错误。当我回到电脑时我会解决它。 – 2012-01-07 23:53:41

+0

固定 - 当我在一点时间压力下写答案时,复制/粘贴错误。对于那个很抱歉! – 2012-01-08 02:10:23

0

是否有任何理由你不使用常规数组?例如;

struct s_stream* streamArray = malloc(sizeof(s_stream*structCount)); 

然后,你必须s_stream的阵列可以只是streamArray访问[0]至streamArray [structCount-1]不解除引用任何额外的指针。

+0

这就是我原来的做法。但是我试图在数组上使用qsort(这是240万个成员),而且这个沉重的递归导致了堆栈溢出。所以试图使用和排序指针,而不是.... – PaeneInsula 2012-01-07 22:04:19