【问题标题】:Passing pointers for memory allocation inside a function?在函数内部传递内存分配指针?
【发布时间】:2012-01-07 20:05:44
【问题描述】:

我需要在我的程序的多个不同位置分配结构数组,从而将工作放在一个函数中(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) ];
}

【问题讨论】:

  • 您到底想做什么 - 是动态分配 struct s_stream 对象的数组吗?
  • 告诉我们编译器的确切警告。特别是,编译器不喜欢哪一行代码?

标签: c database malloc argument-passing


【解决方案1】:

我不确定我是否理解您的问题,但您似乎想要一个函数来创建一个动态分配的 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));
}

【讨论】:

  • 你的第一个 create_array() 应该返回 void* 不是吗?或者更好的 struct stream* 是类型安全的。
  • 是的 - 错字。我会在我回到电脑前修复它。
  • 已修复 - 当我在一些时间压力下编写答案时出现复制/粘贴错误。很抱歉!
【解决方案2】:

您将指针memBlock_1副本 传递给xalloc,因此malloc 返回的地址被写入副本并且永远不会到达调用函数。由于您可能希望地址可用于memBlock_1 中的xxyz,因此您必须将指针指向字符的指针作为第二个参数传递,

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

并使用xalloc(..., &amp;memBlock_1, ...); 调用它。在xalloc 的正文中,将所有出现的memBlock 替换为*memblock,例如(*memblock = malloc(blockSize)) == NULL(无需投射)。

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

【讨论】:

  • 我听从了你的建议;剩下的 2 个问题:编译器不允许:(StreamStruct = malloc(structCount * i))... 我必须转换为 (struct s_stream **)。另一个问题是最后两行,我循环遍历并将指针分配给内存块: for (int i = 0; i sizeof(struct s_stream) ];我得到一个未处理的异常。我在 StreamStruct 和 memBlock 上尝试了很多 * 和 & 的 difft 排列,但没有成功...
  • 如果您需要转换malloc 的结果,这意味着您正在将程序编译为C++,而不是C。这可能没什么大不了的,两者有足够的共同点那么简单程序编译并作为两者工作(在转换malloc返回等之后)。在循环中,它应该是for(...) (*StreamStruct)[i] = &amp;memBlock[...]; - 除非我忽略了一些东西。嗯,“未处理的异常”。是的,C++。如果您正在编译为 C++(使用 Microsoft 的编译器不是一个坏主意,它不支持 C99,但作为 C++ 编译器很好),您可以考虑使用 new 等编写 C++。
  • 哪个是正确的? for(...) (*StreamStruct)[i] = &memBlock[...];或 for(...) (*StreamStruct)[i] = (*memBlock)[...]; ?后者似乎有效,并且与您之前所说的一致......
  • 糟糕,忘了memBlock 也多了一层,(*StreamStruct)[i] = &amp;((*memBlock)[...]); 应该是那个。
  • 知道了。感谢 3 c 的回答(清晰、简洁、有礼貌)!
【解决方案3】:

您有什么理由不使用常规数组吗?例如;

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

然后你有一个 s_stream 数组,你可以使用 streamArray[0] 访问 streamArray[structCount-1] 而无需取消引用任何额外的指针。

【讨论】:

  • 这就是我最初的做法。但是我试图在数组(即 240 万个成员)上使用 qsort,并且大量递归导致堆栈溢出。所以尝试使用和排序指针......
猜你喜欢
  • 2016-02-09
  • 2017-12-13
  • 2018-07-31
  • 2012-03-15
  • 2015-08-22
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多