1
#include <iostream>
#include <string.h>
using namespace std;

void newBuffer(char* outBuffer, size_t sz) {
    outBuffer = new char[sz];
}

int main(void) {

    const char* abcd = "ABCD";
    char* foo;
    foo = NULL;
    size_t len = strlen(abcd);
    cout<<"Checkpoint 1"<<endl;
    newBuffer(foo, len);
    cout<<"Checkpoint 2"<<endl;

    cout<<"Checkpoint 2-A"<<endl;
    memset(foo, '-', len);
    cout<<"Checkpoint 3"<<endl;
    strncpy(foo, abcd, len);
    cout<<"Checkpoint 4"<<endl;
    cout << foo << endl;

    int hold;
    cin>>hold;
    return 0;

}

该程序在检查点 2-1 和 3 之间崩溃。它试图将 char 数组 foo 设置为 char '-',但由于某些访问问题而失败。我不明白为什么会这样。非常感谢您!

4

3 回答 3

6

您的newBuffer函数应该通过引用接受第一个参数,以便调用者可以看到函数内部对其所做的更改:

void newBuffer(char*& outBuffer, size_t sz) {
    outBuffer = new char[sz];
}

就像现在一样,您将结果分配给new char[sz]局部变量,该变量outBuffer只是调用者变量的副本foo,因此当函数返回时,就好像什么都没发生(除了您泄漏的内存)。

此外,您还有一个问题,您将缓冲区分配给长度ABCD为 4 的大小。这意味着您最多可以在该缓冲区中保存 3 个字符,因为最后一个字符是为 NUL 终止符保留的。您需要在+ 1某处添加长度(我会在调用函数时这样做,而不是在函数内部,因为newBuffer不应该专门用于 C 字符串)。strncpy如果源字符串足够短,则只有 NUL 终止缓冲区,所以在这种情况下,您很幸运,0在您分配的缓冲区之后恰好有一个在内存中。

完成后也不要忘记进入delete[] foomain尽管对于这种大小的程序并不重要)。

于 2012-05-13T16:32:57.683 回答
2

它失败了,因为您的newBuffer功能实际上不起作用。修复它的最简单方法是将声明更改为void newBuffer (char *&outBuffer, size_t sz). 正如它所写的那样,新分配的内存地址实际上并没有存储到 main 中foo,因为指针是按值传递的。

于 2012-05-13T16:35:17.227 回答
0

您正在按值传递指针。您需要传递对指针的引用或指针的地址。

也就是说,在我看来,使用返回值会更好:

char* newBuffer(size_t sz) {
    return new char[sz];
}

以这种方式编写时,该newBuffer功能似乎并不值得。你不需要它。你可以new直接使用,这样会更清楚。

当然,如果您使用的是 C++,那么这一切都毫无意义。您应该使用string智能指针等。您不需要new直接调用。一旦你修复了你在这个问题中讨论的错误,你会遇到一个问题,你的字符串不是以空值结尾的,并且缓冲区太短而无法容纳字符串,因为你忘记为空值终止符分配空间。C++ 的优点之一是您可以摆脱 C 中字符串处理的恐惧。

于 2012-05-13T16:36:11.087 回答