我有一节课: .H
class test {
public:
int Length;
char* Name;
int* ARR;
test(int l, char* n, int* a);
test();
};
的.cpp
test::test(int l, char* n, int* a){
Length=l;
Name=n;
ARR=a;
}
和main.cpp
#include<iostream>
void InAFunc(test *kio) {
int foo[3] = { 1,2,3 };
*kio = test(7, "Hello!", foo);
}
int main() {
test mmk;
InAFunc(&mmk);
std::cout << mmk.Name << mmk.ARR[1];
}
据我所知,我可能在ARR上遇到异常,因为变量foo已在函数InAFunc结束时释放。我需要为Arr做新的或malloc以避免它。 我的问题是为什么“你好!”是安全的?我过去编码很多,但从来没有错。为什么在没有new或malloc的构造函数中留下一个字符串是可以的? 此类中的变量名称是指针。
答案 0 :(得分:2)
字符串“Hello”是string literal
,它在程序的持续时间内存在。因此,您可以始终指向它而不会破坏指针。它不会在函数结束时被销毁。
答案 1 :(得分:1)
您的代码有未定义的行为(这意味着无法保证崩溃!),但不是您认为的原因。
InAFunc()
按值获取test
个对象,因此test
对象的副本在{{{ 1}}被调用。 InAFunc()
对其InAFunc()
参数所做的任何修改都是kio
的本地修改,并且不会反映给调用方。
InAFunc()
中的mmk
变量是默认构造的,因此大概main()
和mmk.Name
为NULL(您没有显示该构造函数的代码,虽然),mmk.ARR
不会覆盖它。 未定义行为是将NULL InAFunc()
指针传递给char*
,或者索引到NULL operator<<
指针。
您可能希望int*
输出它创建的新InAFunc()
对象。在这种情况下,test
参数需要通过引用而不是按值传递:
kio
现在void InAFunc(test &kio)
中的mmk
变量将收到main()
分配的值。 <{1}}和InAFunc()
将不再为NULL。
您现在将指向字符串文字的指针指向mmk.Name
,字符串文字驻留在持久性只读存储器中,生命周期为这个过程,因此将mmk.ARR
传递给mmk.Name
将是明确定义的,不会崩溃。
但是,mmk.Name
确实会指向operator<<
本地的数组,并且在mmk.ARR
退出后将不再有效,正如您所怀疑的那样。因此,当您尝试索引到InAFunc()
时,您会有未定义的行为(尽管InAFunc()
指向的内存可能仍会被分配 ,所以代码可能不会崩溃)。
答案 2 :(得分:0)
为什么在没有new或malloc的构造函数中保留字符串是可以的? 为什么在构造函数中将string赋给指针是安全的?
在C ++中,所有都是对象:
debug="true"
是一个对象。因此,指针int
是指向字符串文字所在的位置。
答案 3 :(得分:0)
“hello”的类型是char *(实际上是char [6]),而不是字符串。 char *可以用作字符串,因为隐式转换,std :: string有一个接受char *作为参数的构造函数。 http://en.cppreference.com/w/cpp/string/basic_string/basic_string
btw,“kio = test(...)”无法编译。