更新:正在输出内存位置而不是所需的字符串
Posted
技术标签:
【中文标题】更新:正在输出内存位置而不是所需的字符串【英文标题】:Updated: Memory Location being outputted instead of desired string 【发布时间】:2017-01-22 04:04:22 【问题描述】:->请在水平分隔线下方查看我编辑的问题:
我试图将一个字符串数组从一个函数返回到另一个函数。代码编译成功;但是,它在执行时失败了。我在下面包含了我的代码:
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]
调试器有以下输出:
信号 = SIGSEGV(分段错误)
this = 乘员 * 常量 | 0x61ff2f 0x61ff2f
array = std::_cxx11::basic_string [5]
谁能告诉我我的 return 语句有什么问题,为什么会导致分段错误?谢谢
** 我知道网上还有很多其他类似的问题,但没有一个涉及return语句中的分段错误因此,如果这个问题没有被标记为重复,我将不胜感激。如果您需要更多信息,请在 cmets 框中告诉我。感谢您的帮助!
编辑谢谢大家,我没有注意到我刚刚修复的那个故障。我实际上是想返回整个数组,这次我用指针做到了。这是我的代码:
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:位置
0xf56df8 : 停车
0xf56ea0 : 租用
0xf56d54:位置
0xf56dfc:停车
0xf56ea4:租用
0xf56d58:位置
0xf56e00 : 停车
0xf56ea8 : 租用
0xf56d5c:位置
0xf56e04 : 停车
0xf56eac : 租用
0xf56d60:位置
0xf56e08 : 停车
0xf56eb0 : 租用
我希望在输出内存地址的任何地方都会输出“Hello”字样。现在谁能解释一下?感谢您的所有回答!
【问题讨论】:
数组的索引从0
开始,所以array[5]
越界了。
您的返回类型是 string
,但 array
是 array
的 string
。
是否使用std::Vector
选项?
关于您的笔记,您仍然可能遇到相同的问题并获得不同的行为。一个问题是使用arr[5]
来表示整个数组,而它实际上是一个越界元素,这是一个非常常见的问题。尽管其他人的行为与您的行为不同,但真正的答案是了解如何使用数组,这对您和他们都有帮助。但是,您也有其他问题,例如尝试返回数组,而这不能直接使用 C 数组完成。我建议使用std::array
,因为它更“正常”。
你不能创建一个包含五个东西的数组,然后尝试访问第六个。
【参考方案1】:
要返回一个数组,请使用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
,并返回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
Live Example
无论您选择哪个,请注意不涉及指针。
【讨论】:
第一选择很好用,@PaulMcKenzie,我只是不允许使用向量。与指针相比,这太容易了,我想知道为什么我的教授从来没有教过我这个:/ @NewbietoProgramming -- 实际上,struct
版本是std::array
的精简版。从本质上讲,struct
版本就是 std::array
实际所做的。不同之处在于std::array
有几个成员函数,operator [ ]
重载以访问项目等。【参考方案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
s 数组。目前尚不清楚这是否是意图。如果这是本意,那么调用代码必须负责释放该内存。
调用代码仍然受到超出我们边界内存访问的影响。线
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();
遇到同样的问题。
【讨论】:
我认为 OP 想一次返回所有数组成员 @M.M 这绝对是可能的。我会让 OP 澄清一下。 对不起,@RSahu,这就是我想要做的,但我已经解决了这个问题并最终遇到了一个新问题。请参阅上面的更新。 感谢@RSahu 指出这一点!我一直在犯这样的小错误而没有注意到它。无论如何谢谢:)【参考方案3】:尝试返回array[4]
。没有array[5]
,因为数组从索引 0 开始。
【讨论】:
欢迎来到 Stack Overflow!我推荐你take the tour。【参考方案4】:大小为 N 的数组的范围是从 0 到 N-1。所以 5 不在范围内。并且你可能想要返回一个数组作为结果,但是数组是在函数LoadData
中构造的,函数执行后,数组是无效的。您可以根据需要使用动态分配或使用全局变量。
当你使用动态分配数组时,你可以只使用string*
而不是string**
,你应该释放分配的内存。
【讨论】:
还有return语句? 我刚刚解决了这个问题,你是对的@cstur4,我实际上想返回整个数组。请在上面的问题中查看我的更新:)以上是关于更新:正在输出内存位置而不是所需的字符串的主要内容,如果未能解决你的问题,请参考以下文章