*** Error in `./out': munmap_chunk(): invalid pointer: 0x0000000000400824 ***
给我以下错误:
extern crate rustc_serialize;
use rustc_serialize::json::Json;
use std::fs::File;
use std::io::copy;
use std::io::stdout;
fn main() {
let mut file = File::open("text.json").unwrap();
let mut stdout = stdout();
let mut str = ©(&mut file, &mut stdout).unwrap().to_string();
let data = Json::from_str(str).unwrap();
}
我的问题是,删除bread->名称是否甚至是必要的,或者如果删除面包会为我处理。如果有必要删除bread->名称,为什么程序会在我尝试执行时崩溃?
答案 0 :(得分:8)
问题实际上源于此:
bread->name = "bread";
为name
分配新数组后,您将指针指向一个完全不同的值 - 恰好存在于只读内存中的值。因此,当您删除它时会出现错误:您正在尝试delete []
一个您没有分配的数组。
关键问题是你不想分配指针 name
,你想要填充你刚刚分配的数组的内容 - 你想要填充什么name
指向。为此,strcpy
:
strcpy(bread->name, "bread");
或者真的,因为这是C ++:
struct Product {
std::string name;
float price;
};
Product bread;
bread.name = "bread";
答案 1 :(得分:3)
int main() {
Product * bread = new Product;
bread->name = new char[6];
bread->name = "bread"; // <- Error! Overwriting the pointer value!
delete[] bread->name; // <- Error! Trying to free read-only memory where "bread" is stored...
delete bread;
}
基本上,您使用new char[6]
的常量char数组覆盖动态分配的char数组"bread"
。删除动态分配,您不必删除它。
当您编写"bread"
时,编译器会接收这些字母并将它们存储在只读存储器中。每次编写"bread"
并尝试分配它时,您实际上都会指定一个指向只读内存的指针,或const char*
。
当您分配动态数组时,您在bread->name
指针中存储了动态分配的内存的地址,但是您用不允许释放的只读内存的地址覆盖它即可。因此编译器抱怨它。
在您的代码中,因为您不再拥有指向动态分配的内存的指针new char[6]
,所以您不能再释放它并且还有内存泄漏。
我会这样做(考虑到你对使用字符串的限制)并假设你真的想要动态分配:
int main() {
const char* breadStr = "bread";
int len = strlen(breadStr);
Product * bread = new Product;
bread->name = new char[len + 1];
strncpy(bread->name, breadStr, len + 1); // Copy the string and the \0 (hence the +1)
delete[] bread->name; // no more error!
delete bread;
}
如果不需要动态分配,那么您可以执行以下操作:
int main() {
Product * bread = new Product;
bread->name = "bread";
// You don't have to delete the bread->name since it is NOT dynamically allocated but is in your read-only memory.
delete bread;
}
但我真的更喜欢用@Barry建议的字符串在C ++中完成所有这些。