#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' - ',但由于某些访问问题而失败。我不明白为什么会这样。非常感谢你提前!
答案 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语言中字符串处理的恐怖。