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

Updated: Memory Location being outputted instead of desired string

本文关键字:字符串 输出 位置 内存 更新      更新时间:2023-10-16

->请参阅我在水平分隔符下面编辑的问题:

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

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,并返回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
}

实际示例

无论您选择哪一个,请注意,其中没有涉及指针。

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

当您将数组声明为:时

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的更新实现效果较好,但仍存在一些问题。

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

  2. 调用代码仍然受到越界内存访问的影响。线路

    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**,并且您应该释放分配的内存。