更新:输出内存位置而不是所需的字符串

时间:2017-01-22 04:04:22

标签: c++ arrays string function segmentation-fault

- >请在横向分隔线下面看我编辑过的问题:

我试图将字符串数组从函数返回到另一个函数。代码编译成功;但是,它在执行时失败了。我在下面提供了我的代码:

    string Occupant::LoadDataFunction()
    {
        string array[5] = {"hello", "you", "are", "a", "human"};

        return array[5];
    }

    void Occupant::LoadData()
    {
        string loc_array[5];
        loc_array[5] = Occupant::LoadDataFunction();

        string park_array[5];
        park_array[5] = Occupant::LoadDataFunction();

        string lease_array[5];
        lease_array[5] = Occupant::LoadDataFunction();
    }

当我调试代码时,我发现问题出在函数的return语句中:

    return array[5]

调试器具有以下输出:

  

Signal = SIGSEGV(分段错误)

     

this = {Occupant * const | 0x61ff2f} 0x61ff2f

     

array = {std :: _ cxx11 :: basic_string< char,std :: char_traits,std :: allocator> [5]}

有人能告诉我我的return语句有什么问题,为什么会导致分段错误?感谢

** 我知道网上有很多其他类似的问题,但是没有一个问题涉及return语句中的分段错误。因此,如果这个问题没有标记为重复,我将不胜感激。如果您需要更多信息,请在评论栏中告知我。谢谢你的帮助!

编辑谢谢大家,我没有注意到我刚刚解决的故障。我实际上想要返回整个数组,这次我用指针做了。这是我的代码:

    string* Occupant::LoadDataFunction()
    {
        string* array = new string[5];
        array[0] = "hello";
        array[1] = "hello";
        array[2] = "hello";
        array[3] = "hello";
        array[4] = "hello";

        return array;
    }

    void Occupant::LoadData()
    {
        string **loc_array = new string*[5];
        loc_array[5] = Occupant::LoadDataFunction();

        string **park_array = new string*[5];
        park_array[5] = Occupant::LoadDataFunction();

        string **lease_array = new string*[5];
        lease_array[5] = Occupant::LoadDataFunction();

        for (int i = 0; i < 5; i++)
        {
            cout << &loc_array[i] << " : location" << endl;
            cout << &park_array[i] <<  " : parking" << endl;
            cout << &lease_array[i] <<  " : leased" << endl;
        }
    }

现在的问题是,当我运行代码时,不是总共打印hello十五次,而是打印内存地址。这就是我得到的:

  

0xf56d50:location

     

0xf56df8:停车

     

0xf56ea0:租借

     

0xf56d54:location

     

0xf56dfc:停车

     

0xf56ea4:租借

     

0xf56d58:location

     

0xf56e00:停车

     

0xf56ea8:租借

     

0xf56d5c:location

     

0xf56e04:停车

     

0xf56eac:租借

     

0xf56d60:location

     

0xf56e08:停车

     

0xf56eb0:租借

我期望在输出存储器地址的地方输出“Hello”字。现在有人可以解释一下吗?谢谢你的所有答案!

4 个答案:

答案 0 :(得分:2)

大小为N的数组范围为0到N-1。所以5超出了范围。并且您可能希望返回一个数组作为结果,但是数组是在函数LoadData中构造的,在执行该函数之后,该数组无效。您可以为您的目的使用动态分配或使用全局变量。

当您使用动态分配数组时,您可以使用string*而不是string**,并且应释放已分配的内存。

答案 1 :(得分:2)

您正在使用越界索引访问数组。

当您将数组声明为:

    string loc_array[5];

有效索引为0 - 4

使用

    loc_array[5] = Occupant::LoadDataFunction();

导致未定义的行为。我怀疑你打算使用:

    loc_array[4] = Occupant::LoadDataFunction();

同样,您需要使用:

    park_array[4] = Occupant::LoadDataFunction();

    lease_array[4] = Occupant::LoadDataFunction();

您还需要更改Occupant::LoadDataFunction

string Occupant::LoadDataFunction()
{
    string array[5] = {"hello", "you", "are", "a", "human"};
    return array[4];
}

<强>更新

Occupant::LoadDataFunction的更新实施更好,但仍存在问题。

  1. 每次调用函数时,都会分配一个string的数组。目前尚不清楚这是否意图。如果这是意图,那么调用代码必须负责释放该内存。

  2. 调用代码仍然受到我们的边界内存访问的影响。这条线

    string **loc_array = new string*[5];
    

    5 string*分配内存。 loc_array的有效索引仍为0 - 4。因此,

    loc_array[5] = Occupant::LoadDataFunction();
    

    受到超出内存访问问题的困扰。目前尚不清楚您希望如何使用Occupant::LoadDataFunction的返回值。因此,我无法提出解决问题的方法。

    park_array[5] = Occupant::LoadDataFunction();
    
    lease_array[5] = Occupant::LoadDataFunction();
    

    遇到同样的问题。

答案 2 :(得分:2)

尝试返回array[4]。没有array[5],因为数组从索引0开始。

答案 3 :(得分:2)

要返回数组,请使用std::array,因为std::array是可复制和可分配的,与香草阵列不同。

#include <array>
#include <algorithm>

typedef std::array<std::string, 5> Array5Strings;

Array5Strings LoadDataFunction()
{
    Array5Strings ret;
    std::fill(ret.begin(), ret.end(), "hello");
    return ret;
}

另外,我使用std::fill将项目快速设置为“hello”。

Live Example

如果出于某些奇怪的原因你不能使用std::array,那么另一个选择是创建一个包含5个字符串数组的struct,并返回structstruct是可复制的,因此可以直接从函数返回。

#include <algorithm>
#include <string>
#include <algorithm>
#include <iostream>

struct Array5Strings
{
   std::string sArray[5];
};

Array5Strings LoadDataFunction()
{
    Array5Strings ret;
    std::fill(std::begin(ret.sArray), std::end(ret.sArray), "hello");
    return ret;
}

int main()
{
    Array5Strings val = LoadDataFunction();
    std::cout << val.sArray[0]; // prints the first value
}

Live Example

无论您选择哪种方式,请注意不涉及指针。