0

这可能是一个菜鸟问题。我正在使用果酱 SDK。如果我为 char 数组动态分配一些内存,我会遇到访问冲突。我无法弄清楚我做错了什么。这是使用 malloc 和 free 的有效方式吗?

const char* CClass::caption(int something)
{
    ...

    //char stringPrediction[2000]; // <--- This works

    size_t string01_Size = strlen(string01);
    size_t string02_Size = strlen(string02);

    ...

    stringX = (char *)malloc(string01_Size + string02_Size + 1); // <- Access violation

    strcpy(stringX , string01);
    strcat(stringX , " ");
    strcat(stringX , string02);

    return stringX ;
 }

析构函数:

CClass::~CClass(void)
{
    free(stringX);
}

然后我用它在按钮点击事件上设置标签的标题

... OnClick...(...)
{
    CClass someObject;
    label.setCaption(someObject.caption());
}

单击几下后,我得到访问冲突。

Unhandled exception at 0x1007ECB8 (s3e_simulator_debug.dll) in 
s3e_simulator_debug.exe:    0xC0000005: Access violation writing
location 0x0000000C.

编辑:看来问题是:

  stringX = (char *)malloc(string01_Size + string02_Size + 1);

我没有为此分配空间:

  strcat(stringX , " ");

这应该更好:

  stringX = (char *)malloc(string01_Size + 1 + string02_Size + 1);
4

3 回答 3

0

您基本上已经发现了问题:通过不分配空间,您的第二个 strcat 将溢出并且可能会压缩下一个块的堆指针。需要注意的其他事情(无论如何你可能正在这样做)是在重新分配之前释放 CClass::caption() 中的 stringX,这样你就不会泄漏。无论您真正应该检查 malloc 在使用前是否失败。

正如其他人所建议的那样,使用 std::string 可能会更好。如果需要,您可以随时将它们转换为 char*。当然,如果您这样做,您应该考虑可能会引发异常并相应地进行编程。

于 2013-07-03T05:35:36.200 回答
0

1.您没有测试 malloc 失败的情况。该错误表明您正在尝试取消引用空指针 - malloc 失败时返回的指针。

2. 在计算缓冲区大小时,您似乎没有考虑空字节终止符。假设string01_Sizestring02_Size是不包括空字节的字符数,则您的缓冲区溢出。

这两个动作都会导致未定义的行为。

于 2013-06-12T08:20:35.897 回答
0

在大多数情况下,调用 malloc 或 free 期间遇到的访问冲突表明堆已损坏。由于悬空指针上最常见的溢出或双重释放或释放,发生在较早的某个时间。可能会更早。

从发布的代码中无法推断,因为它实际上是从崩溃开始的。

要处理它,您可以尝试使用 valgrind、应用程序验证程序和其他有助于解决损坏的运行时工具。对于那个特定的问题 - 对于一般来说,您首先不应该在那里,使用 malloc,str* 函数是从 C 继承的所有废话。

一致地使用集合类、字符串类等可以防止过多的情况导致严重的问题。

于 2013-06-12T09:31:29.797 回答