【问题标题】:How to return a char array created in function?如何返回在函数中创建的 char 数组?
【发布时间】:2011-04-13 14:41:16
【问题描述】:

我编程很糟糕已经有一段时间了,我才真正意识到。我之前创建了许多将字符串作为 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[] 。

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

【问题讨论】:

  • 你最好在标签中添加你写的那种代码。
  • 关于问题的第二部分,您必须使用手动循环并将每个字符复制到第二个数组中或使用memcpy...

标签: c++ string scope char


【解决方案1】:

最简单的方法是返回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);
}

【讨论】:

  • 我不同意。虽然这解决了当前的问题,但它并没有解释使用其他类型数组的问题。我不会投反对票,这不公平,但更好的答案可以解释他的初始代码存在的问题。
  • @Alexander:好点子。我已更新我的答案以反映您的评论。
  • 这行得通,我会在一分钟内打勾。所以我认为返回的字符串不会超出范围是正确的,因为它是一个对象返回类型,但一个 char 数组会因为它只是一个指针而不是返回整个数组?
  • @Zac:从概念上讲,首先从 char 数组创建一个临时字符串对象。然后在销毁此临时对象之前将其复制到客户端。从技术上讲,这个副本通常会被优化掉。
  • 好吧我还是有问题,不知道是应该写在这里还是创建一个新线程。我需要以 char 数组而不是字符串类型结束,纯粹因为 char 数组用于包含泵端口名称,即“COM7”,并用作 createfile() 函数中的参数以打开端口写入(实际上一个字符指针)这个函数不接受字符串类型。
【解决方案2】:

在 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 */

考虑问题并不难。

【讨论】:

  • 这解决了问题,除了我什么时候调用 new[] 和什么时候 delete[] ?另外,如果添加的字符串是由 cin >> string 动态分配的呢?内部函数应该由谁知道传递给它的缓冲区的大小?
  • 你在main函数中分配内存。该函数不需要知道缓冲区大小,除非有可能溢出。我会为你更新我的答案。
【解决方案3】:

将数组声明为“静态”变量并返回其地址。 此代码有效,但会导致警告:

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

【讨论】:

  • 什么时候释放静态数组使用的内存?我必须自己做吗?
【解决方案4】:

"Some string\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 数组声明为静态并返回它的地址(如已经建议的那样)。

【讨论】:

    猜你喜欢
    • 2011-08-05
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    相关资源
    最近更新 更多