->请参阅我在水平分隔符下面编辑的问题:
我试图将一个字符串数组从一个函数返回到另一个函数。代码编译成功;然而,它在执行时失败了。我在下面包含了我的代码:
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 array[5]
调试器有以下输出:
Signal=SIGSEGV(分段故障)
this={占用人*常量|0x61ff2f}0x61ff2f
array={std::_cxx11::basic_string<char,std::char_traits,std::分配器>[5]}
有人能告诉我我的返回语句出了什么问题,为什么会导致分段错误吗?感谢
**我知道网上还有很多其他类似的问题,但没有一个涉及return语句中的分段错误。因此,如果这个问题没有标记为重复,我将不胜感激。如果您需要更多信息,请在评论框中通知我。谢谢你的帮助
EDIT谢谢大家,我没有注意到这个小故障,我只是修复了它。我实际上想返回整个数组,这次我用指针完成了。这是我的代码:
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;
}
}
现在的问题是,当我运行代码时,它打印的不是总共打印15次hello,而是内存地址。我得到的是:
0xf56d50:位置
0xf56df8:停车
0xf56ea0:租用
0xf56d54:位置
0xf56dfc:停车
0xf56ea4:租用
0xf56d58:位置
0xf56e00:停车
0xf56ea8:租用
0xf56d5c:位置
0xf56e04:停车
0xf56eac:租用
0xf56d60:位置
0xf56e08:停车
0xf56eb0:租用
我期望一个";你好"在输出存储器地址的任何地方输出的字。现在有人能解释一下吗?谢谢你的回答!
要返回一个数组,请使用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
}
实际示例
无论您选择哪一个,请注意,其中没有涉及指针。
您正在使用越界索引访问数组。
当您将数组声明为:时
string loc_array[5];
有效索引为CCD_ 7-CCD_。
的使用
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
s数组。目前尚不清楚这是否是目的。如果是这样的话,那么调用代码就必须负责释放内存。调用代码仍然受到越界内存访问的影响。线路
string **loc_array = new string*[5];
为CCD_ 12CCD_。
loc_array
的有效索引仍然是0
-4
。因此,loc_array[5] = Occupant::LoadDataFunction();
遭受越界内存访问问题。目前尚不清楚您希望如何使用
Occupant::LoadDataFunction
的返回值。因此,我无法提出解决问题的方法。线路
park_array[5] = Occupant::LoadDataFunction(); lease_array[5] = Occupant::LoadDataFunction();
遭受同样的问题。
尝试返回array[4]
。没有array[5]
,因为数组从索引0开始。
大小为N的数组的范围是从0到N-1。所以5超出了范围。您可能希望返回一个数组作为结果,但该数组是在函数LoadData
中构造的,在执行该函数后,该数组无效。您可以出于自己的目的使用动态分配,也可以使用全局变量。
当您使用动态分配数组时,您可以只使用string*
而不是string**
,并且您应该释放分配的内存。