- >请在横向分隔线下面看我编辑过的问题:
我试图将字符串数组从函数返回到另一个函数。代码编译成功;但是,它在执行时失败了。我在下面提供了我的代码:
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”字。现在有人可以解释一下吗?谢谢你的所有答案!
答案 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
的更新实施更好,但仍存在问题。
每次调用函数时,都会分配一个string
的数组。目前尚不清楚这是否意图。如果这是意图,那么调用代码必须负责释放该内存。
调用代码仍然受到我们的边界内存访问的影响。这条线
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”。
如果出于某些奇怪的原因你不能使用std::array
,那么另一个选择是创建一个包含5个字符串数组的struct
,并返回struct
。 struct
是可复制的,因此可以直接从函数返回。
#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
}
无论您选择哪种方式,请注意不涉及指针。