方法在传递 [] 数组而不是来自 malloc 的内存时有效

Posted

技术标签:

【中文标题】方法在传递 [] 数组而不是来自 malloc 的内存时有效【英文标题】:Method works when passed [] array but not memory from malloc 【发布时间】:2017-04-18 08:53:51 【问题描述】:

如果没有完整的代码,这个问题可能没有意义,但我会尽力解释它。作为背景知识,代码是来自 GitHub 上的 OpenThread 项目的 sn-p,但我相信标准的 c/c++ 原则仍然适用于此。

代码的目的是将一段数据(在本例中为字符串)附加到 OpenThread (ot) 消息上。作为参数,它需要一个 otMessage、一个缓冲区(带有数据)和要复制到 otMessage 中的缓冲区的长度。我不太确定otMessageAppend 是如何工作的,而且完全有可能错误在于它读取缓冲区的方式,如果是这种情况,则无能为力。

以下 c++ 代码是起点:

char command[] = "abcdef";
SuccessOrExit(error = otMessageAppend(message, &command, (uint16_t)strlen(command)*sizeof(char)));

在另一端收到消息时,我收到abcdef

当将abcdef 传递为argv[4] 时,此代码完美运行:

char command[strlen(argv[4])+1];//+1 for the null terminator
strcpy(command, argv[4]);
SuccessOrExit(error = otMessageAppend(message, &command, (uint16_t)strlen(command)*sizeof(char)));

但是尝试使用malloc 分配内存会导致垃圾从另一端流出(正确的字节数但不是正确的数据):

char *command;
command = (char *) malloc(strlen(argv[4])+1);
strcpy(command, argv[4]);
SuccessOrExit(error = otMessageAppend(message, &command, (uint16_t)strlen(command)*sizeof(char)));

我对此有几个问题:

    使用char array[size] 声明内存有什么问题吗?据我了解,区别在于使用[] 将在堆栈中分配内存,而malloc 在堆中分配内存。 如果我应该使用malloc,我如何确保正确的内存将“附加到消息中”而不仅仅是垃圾

如果知道otAppendMessage 的工作原理很重要,我可以挖掘源代码并找到它。

【问题讨论】:

command 是指针时,&command 具有不同的含义。你得到一个指向指针的指针,而不是指向字符串的指针。 您是在编程 C 还是 C++?它们是不同的语言,并且行为确实不同。考虑到您使用variable-length arrays 和malloc,我假设您实际上是用C 编程的(在这种情况下,您应该阅读this discussion about casting the result of malloc)? 如果是 c++,那为什么不用new 而不是malloc?为什么不用std::string 而不是char* 编译时启用警告!并理解警告。 无论哪种方式,在不知道 otMessageAppend 的确切声明(Minimal, Complete, and Verifiable Example 会有所帮助)的情况下,您可能希望在构建时启用更多警告。对真正的数组(不是指针)使用 address-of 运算符通常是不会做的,如果参数不匹配,您会收到有关它的警告(或 C++ 中的错误)。 【参考方案1】:

&command 替换为command

两个 sn-ps 都不好,但是第一个恰好起作用,因为数组的地址与其第一个元素的地址相同,并且如果参数的类型为 void*,则两个表达式都会导致相同的转换参数。在第二个 sn-p 中,指针的地址肯定等于指针的值(因为 malloc 的无别名保证)。

【讨论】:

如果 sn-ps 不好,我可以做些什么来改进它们,malloc 这样做有什么好处 @CampbellWray:你可以做些什么来改进它们,就像答案所说的那样,用command 替换&command。使用自动内存还是动态内存取决于您更大的设计要求(字符串大小、寿命);您需要自己做出决定。 @CampbellWray 您需要在两个版本中删除& 感谢@AnttiHaapala 和Kerrek,我是在别人的代码之上构建的,所以我在很大程度上遵循他们所拥有的,因此& @CampbellWray:我应该说,从洞察力和深思熟虑的角度进行编程可能比通过模式匹配、语法猜测和遵循食谱更有效。这个主题很复杂,通过拼凑不透明的构建块,你不太可能走得很远。

以上是关于方法在传递 [] 数组而不是来自 malloc 的内存时有效的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中将数组作为参数而不是数组传递

使用 new 而不是 malloc 分配内存

在 Matlab 中使用 Globals 而不是传递大型数组

来自 p:ajax 中的侦听器的 InputText 值传递 null 而不是 value

通过引用而不是按值传递 OpenCV C++

通过 c 中的管道而不是文件将数据数组传递给 gnuplot