[英]Access violation writing location 0x00000000. memset function issues
#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'-',但由於某些訪問問題而失敗。 我不明白為什么會這樣。 提前非常感謝您!
您的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
。
另外,不要忘記在main
delete[] foo
(盡管對於這樣大小的程序,它實際上並不重要)。
它失敗,因為您的newBuffer
函數實際上不起作用。 最簡單的解決方法是將聲明更改為void newBuffer (char *&outBuffer, size_t sz)
。 在編寫時,新分配的內存的地址實際上並未存儲到main的foo
因為指針是通過值傳遞的。
您正在按值傳遞指針。 您將需要傳遞對指針的引用或指針的地址。
也就是說,在我看來,使用返回值會更好:
char* newBuffer(size_t sz) {
return new char[sz];
}
用這種方式編寫時, newBuffer
函數似乎並不值得。 不用了 您可以直接使用new
,這樣會更清晰。
當然,如果您使用的是C ++,那么這一切都是毫無意義的。 您應該使用string
,智能指針等。您不需要直接調用new
。 修復了您在該問題中所討論的錯誤后,您會遇到一個問題,即您的字符串不是以空字符結尾的,並且緩沖區太短而無法容納該字符串,因為您忘記為空字符結尾的空間。 C ++的優點之一是您可以避免使用C進行字符串處理的恐懼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.