【问题标题】:Return 2D char array from function in c++ and print it从 C++ 中的函数返回 2D 字符数组并打印它
【发布时间】:2020-06-22 22:16:45
【问题描述】:

这是我的代码,我想从我的函数中返回二维数组 [10][8] 和 [10][20],但我得到一个错误! (分段错误)。

请帮帮我!!我的项目需要这个。最后我想打印这个数组,但由于错误我不能这样做。

有人可以帮我解决这个问题并打印那个吗?

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>

using namespace std;

char **getWords(int level)
{
    if (level == 1)
    {
        char **words = new char *[8];
        strcpy(words[0], "Pakistan");
        strcpy(words[1], "Portugal");
        strcpy(words[2], "Tanzania");
        strcpy(words[3], "Thailand");
        strcpy(words[4], "Zimbabwe");
        strcpy(words[5], "Cameroon");
        strcpy(words[6], "Colombia");
        strcpy(words[7], "Ethiopia");
        strcpy(words[8], "Honduras");
        strcpy(words[9], "Maldives");
        return words;
    }
    //For Hard Level
    else if (level == 2)
    {
        char **words = (char **)malloc(sizeof(char *) * 20);
        strcpy(words[0], "Tajikistan");
        strcpy(words[1], "Uzbekistan");
        strcpy(words[2], "Azerbaijan");
        strcpy(words[3], "Bangladesh");
        strcpy(words[4], "Luxembourg");
        strcpy(words[5], "Madagascar");
        strcpy(words[6], "Mauritania");
        strcpy(words[7], "Montenegro");
        strcpy(words[8], "Mozambique");
        strcpy(words[9], "New Zealand");

        return words;
    }
}

int main()
{
    getWords(1);

    return 0;
}

【问题讨论】:

  • 在调试器中运行代码并单步执行。找出你在哪一行得到段错误。这将帮助您缩小问题的范围。如果您不知道如何使用调试器,现在是学习的好时机。
  • 如果这是 c++,为什么不使用std::vector&lt;std::string&gt;。它会让一切变得更容易。
  • 在对字符串执行strcpy() 之前,必须为字符串分配缓冲区。
  • 从函数返回一个局部指针变量简直是灾难! wordsgetWords 函数堆栈上的局部变量。你知道当控制从函数返回到调用行时会发生什么吗?
  • 在同一个指针中混合mallocnew 是一个非常糟糕的主意。无法通过指针判断您需要使用 deletefree 中的哪一个来重新放回内存。

标签: c++ memory-management malloc new-operator dynamic-memory-allocation


【解决方案1】:

通过做

char **words = new char *[10];

您只是为指针分配内存,而不是为要存储实际字符串的内存块分配内存,您也需要为此分配内存:

char **words = new char *[10]; //space for 10 pointers
        
for(int i = 0; i < 10; i++){
    words[i] = new char[10]; // space for 10 characters each line, 8 is not enough
}                            // you need at least 9 because of the ending nul byte

strcpy(words[0], "Pakistan");
strcpy(words[1], "Portugal");
//...

在 main 中,将它们分配给指向指针的指针并将它们打印出来,就像它是一个字符串数组一样:

char** words = getWords(1);

for(int i = 0; i < 10; i++){
    std::cout << words[i] << std::endl;
}

Live demo

使用malloc的第二部分也是如此。

char **words = (char**)malloc(sizeof *words * 10); //space for 10 pointers

for(int i = 0; i < 10; i++){
    words[i] = (char*) malloc(20); //space for 20 characters each line
}

Live demo

在正常情况下,当程序没有立即结束时,您必须释放内存:

对于使用new分配的内存:

for (int i = 0; i < 10; i++) 
{
    delete words[i];
}
delete words;

对于malloc分配的内存:

for(int i = 0; i < 10; i++)
{
    free(words[i]);
}
free(words);  

这在您的情况下可能会很棘手,因为您返回 2 种类型的内存分配取决于您作为参数传递的选项,我的建议是您使用相同的选项来选择如何释放内存。

P.S.:使用像 std::vectorstd::string 这样的 C++ 容器会让你的工作更轻松,你不需要自己处理内存。

【讨论】:

  • 哇你太棒了@anastaciu Tnx !!你修复我的鳕鱼
  • @kasra,谢谢,我受宠若惊,我很高兴能帮上忙。
【解决方案2】:

使用

 char **words =new char*[8];
 strcpy(words[0],"Pakistan");

这是一个问题,因为您没有为words[0] 分配内存。

类似于

 char* cp; /// Uninitialized pointer
 strcpy(cp,"Pakistan");

在调用strcpy 之前,您必须为words[0]words[1] 等分配内存。

更重要的是,改变你的策略,改用std::vector&lt;std::sting&gt;。这使您的代码更简单,并消除了从应用程序代码分配和释放内存的负担。

std::vector<std::string> getWords(int level)
{
     std::vector<std::string> words;
     if (level==1)
     {
         words.push_backl("Pakistan");
         // etc.

     
     return words;
}

【讨论】:

  • 我等待传统的-“我不允许使用字符串或向量”
  • @pm100,你做作业的时候总有可能:)
猜你喜欢
  • 1970-01-01
  • 2021-03-16
  • 1970-01-01
  • 2018-12-29
  • 2018-10-30
  • 2014-04-11
  • 2013-11-22
  • 2013-03-25
  • 1970-01-01
相关资源
最近更新 更多