Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;在没有对象初始化的情况下调用函数_C++_Pointers_Object_Initialization - Fatal编程技术网

C++ C++;在没有对象初始化的情况下调用函数

C++ C++;在没有对象初始化的情况下调用函数,c++,pointers,object,initialization,C++,Pointers,Object,Initialization,为什么要运行以下代码 #include <iostream> class A { int num; public: void foo(){ num=5; std::cout<< "num="; std::cout<<num;} }; int main() { A* a; a->foo(); return 0; } 我使用gcc编译它,在第10行只得到以下编译器警告: (警告:此函数未初始化时使用

为什么要运行以下代码

#include <iostream>
class A {
    int num;
    public:
        void foo(){ num=5; std::cout<< "num="; std::cout<<num;}
};

int main() {
    A* a;
    a->foo();
    return 0;
}
我使用gcc编译它,在第10行只得到以下编译器警告:

警告:此函数未初始化时使用了“a”

但根据我的理解,这段代码不应该运行吗?当num不存在,因为还没有创建类型为A的对象时,它怎么会将值5赋给num呢

A* a;
a->foo();
调用未定义行为的。最常见的情况是程序崩溃

C++03标准第§4.1/1节规定:

a的左值(3.10) 非函数、非数组类型T可以是 转换为右值。如果T是一个 不完整类型,一个 这种转换是必要的 格式不正确。如果 左值引用不是类型为的对象 并且不是类型的对象 从T派生,或如果对象是 未初始化的程序 必须进行这种转换 未定义的行为。如果T是一个 非类类型,右值的类型 是T的cv不合格版本。 否则,右值的类型为 T

请参见类似主题:


当num不存在,因为还没有创建类型为A的对象时,为什么要将值5赋给num呢


这叫做幸运。但是它不会总是发生是未初始化的指针

您看到的值是垃圾,您很幸运没有以崩溃告终

这里没有初始化

这里没有作业

您的类恰好足够简单,不会显示更严重的问题

A*A(0)将导致崩溃。在某些情况下,未初始化的指针会导致崩溃,并且更容易使用更复杂的类型进行复制


这是处理未初始化指针和对象的结果,它指出了编译器警告的重要性。

您还没有初始化
*a

试试这个:

#include <iostream>

class A
{
    int num;
    public:
        void foo(){ std::cout<< "num="; num=5; std::cout<<num;}
};

int main()
{
    A* a = new A();
    a->foo();
    return 0;
}

“不吉利”(使调试程序更容易,所以我不认为它是“不吉利的”,真的):


创建对象时,即使不使用关键字
new
,也会为该特定对象分配类成员,因为该对象是指向类的指针。因此,您的代码运行良好,并为您提供值
num
,但GCC会发出警告,因为您没有显式地实例化对象。

代码会产生未定义的行为,因为它试图取消引用未初始化的指针。未定义的行为是不可预测的,不遵循任何逻辑。因此,任何关于代码为什么做某事或不做某事的问题都毫无意义

你在问为什么它会运行?它不跑了。它产生未定义的行为

您询问它如何将5分配给不存在的成员?它不会给任何东西赋值。它产生未定义的行为

您是说输出是
5
?错。输出不是
5
。没有有意义的输出。代码生成未定义的行为。仅仅因为在你的实验中碰巧打印了
5
,就意味着完全没有任何意义,也没有任何有意义的解释。

我将(呵呵)向你指出我之前对一个非常类似问题的回答:

基本上,您正在用指针覆盖
envs
堆栈变量,因为您没有将
envs
添加到
main
声明中

由于
envs
是一个数组(字符串)数组,它实际上分配得非常多,您将用
5
覆盖该列表中的第一个指针,然后再次读取它以使用
cout
打印


这就是为什么会发生这种情况的答案。显然,你不应该依赖于此。

我认为这就是发生的事情

a->foo()
因为您只是在调用
A::foo(A)。

a
是main调用堆栈中的指针类型变量<当访问位置
a
时,code>foo()
函数可能会抛出分段错误,但如果没有,则
foo()
只从a跳转一些位置,并用值5覆盖4个字节的内存。然后读取相同的值

我是对还是错?请让我知道,我正在学习呼叫堆栈,如果您对我的回答有任何反馈,我将不胜感激

还要看下面的代码

#include<iostream>
class A {
    int num;
    public:
        void foo(){ num=5; std::cout<< "num="; std::cout<<num;}
};

int main() {

    A* a;
    std::cout<<"sizeof A is "<<sizeof(A*)<<std::endl;
    std::cout<<"sizeof int is "<<sizeof(int)<<std::endl;
    int buffer=44;
    std::cout<<"buffer is "<<buffer<<std::endl;
    a=(A*)&buffer;

    a->foo();
    std::cout<<"\nbuffer is "<<buffer<<std::endl;
    return 0;
}
#包括
甲级{
int-num;
公众:

void foo(){num=5;std::coutI怀疑该值是否为垃圾。如果我将foo中num的值从num=5更改为num=any数字,我会在输出时得到该数字。它肯定是垃圾-通过写入num的值,您正在覆盖内存中附近其他对象的地址。Apoorva Iyer,您显然不理解“未定义的行为。”哦,那样的话。所以我覆盖了其他一些垃圾地址!我以为你的意思是num的值是垃圾。这更有意义。谢谢!另外,由于缺少赋值而“获取”的值是垃圾(特别是)。除此之外,你要么访问有效的内存地址,要么访问无效的内存地址(==崩溃或非常神秘的行为)。我故意没有初始化*a。重点是我可以在foo()中设置'num'的值没有初始化*a!可能是+1的重复。另外一个问题:如果没有成员
num
,你应该能够期待这项工作吗?例如,如果它只包含
std::cout@Merlyn Morgan Graham:不。这里的代码反引用了未初始化的指针。这是未定义的行为(即程序可能做任何事情(包括看起来工作))@Martin:我想我可以看到规范没有定义这一点,所以你不应该依赖它,但是
// uninitialized memory 0x00000042 to 0x0000004B
A* a;
// a = 0x00000042;
*a = "lalalalala";
// "Nothing" happens
void* a;
// a = &main;
*a = "lalalalala";
// Not good. *Might* cause a crash.
// Perhaps someone can tell me exactly what'll happen?
#include<iostream>
class A {
    int num;
    public:
        void foo(){ num=5; std::cout<< "num="; std::cout<<num;}
};

int main() {

    A* a;
    std::cout<<"sizeof A is "<<sizeof(A*)<<std::endl;
    std::cout<<"sizeof int is "<<sizeof(int)<<std::endl;
    int buffer=44;
    std::cout<<"buffer is "<<buffer<<std::endl;
    a=(A*)&buffer;

    a->foo();
    std::cout<<"\nbuffer is "<<buffer<<std::endl;
    return 0;
}