如何返回在函数中创建的字符数组?

问题描述:

我已经编程很糟糕了很长一段时间,我只是真正意识到。我以前创建了许多将字符串作为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; 
} 

我想,以填补该指针解析指向但这并不”在上面的代码中发生的阵列。

另外,什么时候应该使用新的[]命令来创建我的数组?需要吗?什么时候应该调用它的delete []。

非常感谢这一点,它显然非常基本,但我一直在做错了一段时间。

+1

你最好添加你在代码中写的代码。 – Stefanvds 2010-09-17 08:03:03

+0

关于你的问题的第二部分,你将不得不手动循环和复制每个字符到第二个数组或使用'memcpy' ... – st0le 2010-09-17 08:03:50

最简单的方法是返回std::string,如果您需要访问内部字符数组,请使用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); 
} 
+6

我不同意。虽然这解决了当前的问题,但它没有解释使用其他类型的数组的问题。我不会低估,这是不公平的,但更好的答案可以解释他最初的代码存在的问题。 – 2010-09-17 08:09:53

+0

对于'std :: string',普通的旧C数组是*所以*不是C++ ... – fredoverflow 2010-09-17 08:24:17

+1

@Alexander:好点。我已更新我的回答以反映您的评论。 – Paul 2010-09-17 08:25:08

您有两种选择以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 */ 

它当你想到这个问题并不难。

+0

除了何时调用new []和何时删除[]时,这可以解决问题?另外如果添加的字符串是由cin >> string动态分配的呢?谁应该知道内部函数传递给它的缓冲区的大小? – Zac 2010-09-17 08:23:20

+0

您在主函数中分配内存。该函数不需要知道缓冲区大小,除非有可能发生溢出。我会为你更新我的答案。 – 2010-09-17 10:08:04

声明数组为“静态”变量并返回其地址。 此代码的工作,但会导致一个警告:

#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; 
} 
+0

什么时候释放静态数组所使用的内存?我自己必须这样做吗? – 2013-12-09 03:37:44

“一些字符串\ 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并返回它的地址(如已经建议的那样)。