访问冲突写入位置0x00000000。 memset函数问题

时间:2012-05-13 16:31:08

标签: c++ string

#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' - ',但由于某些访问问题而失败。我不明白为什么会这样。非常感谢你提前!

3 个答案:

答案 0 :(得分:6)

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

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

就像现在一样,您将new char[sz]的结果分配给本地变量outBuffer,它只是来电者foo变量的副本,所以当函数返回时,好像什么也没发生过(除了你泄漏了内存)。

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

完成后,delete[] foo也不要忘记main(虽然这个大小的程序并不重要)。

答案 1 :(得分:2)

失败是因为您的newBuffer功能实际上无效。解决问题的最简单方法是将声明更改为void newBuffer (char *&outBuffer, size_t sz)。在编写时,新分配的内存的地址实际上并没有存储到main foo中,因为指针是按值传递的。

答案 2 :(得分:0)

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

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

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

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

当然,如果您使用的是C ++,那么这一切都毫无意义。您应该使用string,智能指针等。您不需要直接致电new。一旦你修复了你在这个问题中讨论的错误,你就会遇到这样的问题:你的字符串不是以空值终止的,并且缓冲区太短而无法容纳字符串,因为你忘了为空终止符分配空间。关于C ++的一个好处是你可以逃避C语言中字符串处理的恐怖。