我已经编程了很长一段时间,我才真正意识到。我之前创建了许多函数,它们将字符串作为char数组返回(或至少指向它们的指针)。
前几天有人指出,当我的函数返回时,我的函数指向的char数组已超出范围,我现在基本上指向一个随机的内存(一个令人讨厌的悬空指针)。
我暂时没有注意到这一点,因为输出到控制台时的char数组似乎没有损坏(可能是因为没有时间覆盖该数据)。当我返回一个通过读取经常损坏的串口生成的字符串缓冲区(char数组)时,我注意到了这一点。
那么,我该如何做到最好?
我的错误代码如下:
#include <cstdlib>
#include <iostream>
using namespace std;
char* myBadFunction(){
char charArray[] = "Some string\n";
char* charPointer = charArray;
return charPointer;
}
int main(int argc, char** argv) {
cout << myBadFunction();
return 0;
}
我理解我应该在调用函数之前在程序中分配内存或者创建一个全局变量来放入返回的字符串,但是如果我的被调用函数被许多不同的程序使用,那么它应该如何知道它的大小预先将缓冲区传递给它,何时删除此内存?
以下代码也没有按照我的要求正确执行:
#include <cstdlib>
#include <iostream>
using namespace std;
void fillArray(char* charPointer){
char charArray[] = "Some string\n"; // Create string
charPointer = charArray; // Not correct, want to fill predefined array with created string
return;
}
int main(int argc, char** argv) {
char predefinedArray[50] = {0};
fillArray(predefinedArray);
cout << predefinedArray;
return 0;
}
我想填充指针解析指向的数组,但这不会发生在上面的代码中。
另外,我何时应该使用new []命令创建我的数组?它需要吗?什么时候应该在上面调用delete []。
非常感谢这一点,这显然是非常基本的,但我有一段时间做错了。
答案 0 :(得分:10)
最简单的方法是返回std::string
,如果需要访问内部char数组,请使用std::string::c_str()
。
#include <iostream>
#include <string>
using namespace std;
string myGoodFunction(){
char charArray[] = "Some string\n";
return string(charArray);
}
int main(int argc, char** argv) {
cout << myGoodFunction();
return 0;
}
如果需要返回除char数组以外的其他内容,请记住指针可以用作迭代器。这允许您将数组封装在矢量或类似结构中:
vector<int> returnInts() {
int someNums[] = { 1, 2, 3, 4 };
return vector<int>(someNums, someNums + 4);
}
答案 1 :(得分:6)
在C ++中有两个返回数组的选项。你可以填写预先分配的内存(好),或者在函数中分配你自己的内存并返回它(坏)。首选的原因是它重新强制正确处理已分配的内存。
一个基本的例子如下:
void fillArray(char* buffer, int sz) {
char text[] = "hello there!";
if (sizeof(text)>sz) {
// overflow! Buffer is too small!
return;
}
for (int n=0;n<sizeof(text);n++) {
buffer[n] = text[n];
}
}
int main() {
char* buffer = new char[30]; // allocates a buffer of 30 bytes.
fillArray(buffer,30);
cout << buffer;
delete [] buffer;
}
/* note that it would be easier to use static memory in this example */
当你想到这个问题时并不难。
答案 2 :(得分:2)
将数组声明为“static”变量并返回其地址。 此代码有效,但会发出警告:
#include <cstdlib>
#include <iostream>
using namespace std;
char* myBadFunction(){
static char charArray[] = "Some string\n"; // insert "static"
// char* charPointer = charArray;
return charArray; // charArray is a pointer to the static array
} // after returning static varibles stay safe
int main(int argc, char** argv) {
cout << myBadFunction();
return 0;
}
答案 3 :(得分:1)
“某些字符串\ n”是字符串文字,因此在程序的生命周期内存在,因此以下内容有效:
#include <cstdlib>
#include <iostream>
using namespace std;
char* myGoodFunction(){
char* charPointer = "Some string\n";
return charPointer;
}
int main(int argc, char** argv) {
cout << myGoodFunction();
return 0;
}
当然,这仅在函数始终返回相同字符串时才有用。如果返回的字符串可以变化(通常是这种情况),那么您可以将函数中的char数组声明为static并返回它的地址(如已经建议的那样)。