精华内容
下载资源
问答
  • vector保存指向局部变量指针:不可以,因为局部变量离开作用域后,就会释放,指向局部变量指针会指向未知的地址空间,指向的内容未知。 demo1:验证vector即使局部变量也是堆上上分配。 结果:返回的vector中...

    一、结论

    vector保存局部变量:可以,因为在vector上创建对象也是在堆上;

    vector保存指向局部变量的指针:不可以,因为局部变量离开作用域后,就会释放,指向局部变量的指针会指向未知的地址空间,指向的内容未知。

    demo1:验证vector即使局部变量也是堆上上分配。

    结果:返回的vector中保存的局部变量地址没有变化。

    #include <iostream>
    #include <vector>
    using namespace std;
    
    // 返回一个vector变量,并打印vec的地址和存放在容器中第一个数据的首地址
    vector<int> fun() {
        vector<int> vec;    // 创建vector
        vec.push_back(10);   // 添加一个元素
    
        cout << "fun():&vec" << &vec << endl;
        cout << "fun():&vec[0]" << &vec[0] << endl;
    
        return vec;   // 返回vector
    
    }
    
    int main() {
        vector<int> vec;   // 创建一个vector
        vec = fun();      // 接收传来的参数
    
        cout << "----------------------" <<endl;
    
        cout << "main():&vec" << &vec << endl;
        cout << "main():&vec[0]" << &vec[0] << endl;
        return 0;
    }
    

    Ref:https://xie.infoq.cn/article/bc30c36a64ed67985cf7c8da1

    二、拓展

    vector是在堆上分配对象,那么怎么释放堆上的空间,避免内存泄露?
    Answer:提供有两个方法,clear()、swap(),可以看看官网说明。
    clear是清空vector,size变0,capacity不变
    swap是size变0,capacity变0

    void clear() noexcept;
    Clear content
    Removes all elements from the vector (which are destroyed), leaving the container with a size of 0.
    
    A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. A typical alternative that forces a reallocation is to use swap:
     
    vector<T>().swap(x);   // clear x reallocating 
    

    demo2:验证clear和swap方法

    #include <iostream>
    #include <vector>
    using namespace std;
    void func()
    {
        vector<int> v;
        v.push_back(1);
        v.push_back(2);
        v.push_back(3);
        v.push_back(4);
        v.push_back(5);
    
        cout << "size:" << v.size() << endl;
        cout << "capacity:" << v.capacity() << endl;
    
        v.clear();
        cout << "after clear size:" << v.size() << endl;
        cout << "after clear capacity:" << v.capacity() << endl;
    
        vector<int>().swap(v);
        cout << "after swap size:" << v.size() << endl;
        cout << "after swap capacity:" << v.capacity() << endl;
    }
    
    int main() {
        func();
        return 0;
    }
    

    最后:问题来了,STL为什么这么设计?

    展开全文
  • 当返回局部对象的值时,会产生一个临时对象,局部对象将值拷贝给该临时对象(拷贝构造),所以当函数结束时,尽管局部已经析构了,但是它保存了一个副本在临时对象中,当函数接收完局部对象的值后(其实此时又进行了一...

    当返回局部对象的值时,会产生一个临时对象,局部对象将值拷贝给该临时对象(拷贝构造),
    所以当函数结束时,尽管局部已经析构了,但是它保存了一个副本在临时对象中,当函数接收完局部对象的值后(其实此时又进行了一次拷贝)临时对象析构。
    但返回局部对象的引用时,就出问题了,因为引用相当于是一个别名,也就是说返回局部引用所对应的内存快的内容给函数返回的接收对象,当函数结束时,局部对象被析构,内

    存块的内容变为未定义内容,所以出错。指针也是同样的原因。


    为 class A 重载一个拷贝构造函数

    #include <iostream>
    using namespace std;

    class A
    {
    public:
        A()
        {
            cout<<"本体"<<endl;
        }
        A(const A& CA)
        {
            cout<<"分身"<<endl;
        }
        ~A()
        {

        }
    };

    A fun();

    int main()
    {
        fun();
        return 0;
    }

    A fun()
    {
        A a;
        return a;
    }


    然后再跑跑代码看看。


     

    转载于:https://www.cnblogs.com/BeyondTechnology/archive/2010/10/13/1850548.html

    展开全文
  • 返回指向局部变量指针或引用

    千次阅读 2014-11-04 08:57:03
    返回指向局部变量指针才有问题, 函数退栈之后,局部变量消失, 指针将指向未知区域,所以出现问题。 返回局部变量的引用也是绝对不可以的。 引用只是变量的一个别名,变量本体都不存在了,引用当然也...
    返回局部变量没问题 如果返回局部变量有问题,函数的意义还有吗? 全局变量还用返回吗? 

    返回指向局部变量的指针才有问题, 函数退栈之后,局部变量消失, 指针将指向未知区域,所以出现问题。

    返回局部变量的引用也是绝对不可以的。 引用只是变量的一个别名,变量本体都不存在了,引用当然也没有任何意义。 

    还有,如果是堆空间,可以返回,即在函数中用new申请的空间,是可以返回的

    但是一般的情况下,好的风格是: 
    尽量在同一个作用域内成对使用new   和delete,(也即不要返回堆空间),因为如果不是这样,会是你的函数的接口变的不够灵活, 试想每个调用你的函数的人还需要记得去delete掉你在函数中new的堆空间, 否则就会造成内存泄露。

    返回啥其实都是值拷贝! 指针就是指针值拷贝,   不会拷贝被指向的内容。

    永远不要从函数中返回局部自动变量的地址。如果你真的需要这样操作。你可以在函数的参数表中传入一个指针变量然后将需要写入的数据写入到该指针变量指向的地址。由于该指针指向的变量,作用域在函数体 之外。因此不会在函数结束结束时被回收。


    在C语言中为什么说绝不能返回函数内局部变量的地址?
    在程序中,只在特定的过程或函数中可以访问的变量,是相对与全局变量而言的。
    全局变量也称为外部变量,是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。全局变量全部存放在静态存储区,在程序开始执行时给全局变量分配存储区,程序行完毕就释放。
    局部变量可以和全局变量重名,但是局部变量会屏蔽全局变量。在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。
    
    
    局部变量的特点是:随函数调用时创建 随函数结束时析构(销毁)。
    设想,如果返回了一个局部变量的指针,而恰好局部变量偏偏又在函数结束后销毁,但指针并没有被销毁,而是被返回,那也就是说,指针指向的正是一个被销毁了的对象。
    一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。

        下面以函数返回局部变量的指针举几个典型的例子来说明:

    1:

    1. #include <stdio.h>    
    2. char *returnStr()   
    3. {   
    4.     char *p="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.     str=returnStr();   
    11.     printf("%s\n", str);   
    12.     return 0;   
    13. }  
    这个没有任何问题,因为"hello world!"是一个字符串常量,存放在只读数据段,把该字符串常量存放的只读数据段的首地址赋值给了指针,所以returnStr函数退出时,该该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。

    2:

    1. #include <stdio.h>   
    2. char *returnStr()   
    3. {   
    4.     char p[]="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.     str=returnStr();   
    11.     printf("%s\n", str);   
    12.     return 0;   
    13. }   
    "hello world!"是局部变量存放在栈中。当returnStr函数退出时,栈要清空,局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,所以有可能打印出来的是乱码。 

    3:

    1. int func()  
    2. {  
    3.       int a;  
    4.       ....  
    5.       return a;    //允许  
    6. }                     
    7.   
    8. int * func()  
    9. {  
    10.       int a;  
    11.       ....  
    12.       return &a;    //无意义,不应该这样做  
    13.   

    局部变量也分局部自动变量和局部静态变量,由于a返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,

    因为这时候返回的是这个局部变量的值,但不应该返回指向局部自动变量的指针,因为函数调用结束后该局部自动变量

    被抛弃,这个指针指向一个不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量的生存

    期从定义起到程序结束。

    4:如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型。如下:
    1. #include <stdio.h>   
    2. char *returnStr()   
    3. {   
    4.     static char p[]="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.      str=returnStr();   
    11.     printf("%s\n", str);   
    12.   
    13.     return 0;   
    14. }   
    5: 数组是不能作为函数的返回值的,原因是编译器把数组名认为是局部变量(数组)的地址。返回一个数组一般用返回指向这个数组的指针代替,而且这个指针不能指向一个自动数组,因为函数结束后自动数组被抛弃,但可以返回一个指向静态局部数组的指针,因为静态存储期是从对象定义到程序结束的。如下:

    1. int* func( void )  
    2. {  
    3.     static int a[10];  
    4.     ........  
    5.     return a;  
    6. }   

    6:返回指向堆内存的指针是可以的

    1. char *GetMemory3(int num)  
    2. {  
    3. char *p = (char *)malloc(sizeof(char) * num);  
    4. return p;  
    5. }  
    6. void Test3(void)  
    7. {  
    8. char *str = NULL;  
    9. str = GetMemory3(100);  
    10. strcpy(str, "hello");  
    11. cout<< str << endl;  
    12. free(str);  
    13. }  
    程序在运行的时候用 malloc 申请任意多少的内存,程序员自己负责在何时用 free释放内存。动态内存的生存期由程序员自己决定,使用非常灵活。
    展开全文
  • 一般的来说,函数是可以返回局部变量...因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意

    一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。

    函数返回值时,要生成一个值的副本。而用引用返回值时,不生成值的副本,所以提高了效率(返回指向函数的指针也一样)

    返回数值 返回引用

    下面以函数返回局部变量的指针举几个典型例子:

    1:

    1. #include <stdio.h>    
    2. char *returnStr()   
    3. {   
    4.     char *p="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.     str=returnStr();   
    11.     printf("%s\n", str);   
    12.     return 0;   
    13. }  

    这个没有任何问题,因为"hello world!"是一个字符串常量,存放在只读数据段,把该字符串常量存放的只读数据段的首地址赋值给了指针,所以returnStr函数退出时,该该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。

    2:

    1. #include <stdio.h>   
    2. char *returnStr()   
    3. {   
    4.     char p[]="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.     str=returnStr();   
    11.     printf("%s\n", str);   
    12.     return 0;   
    13. }   

    "hello world!"是局部变量存放在栈中。当returnStr函数退出时,栈要清空,局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,所以有可能打印出来的是乱码。 

    3:

    1. int func()  
    2. {  
    3.       int a;  
    4.       ....  
    5.       return a;    //允许  
    6. }                     
    7.   
    8. int * func()  
    9. {  
    10.       int a;  
    11.       ....  
    12.       return &a;    //无意义,不应该这样做  
    13. }   

    局部变量也分局部自动变量和局部静态变量,由于a返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,

    因为这时候返回的是这个局部变量的值,但不应该返回指向局部自动变量的指针,因为函数调用结束后该局部自动变量

    被抛弃,这个指针指向一个不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量的生存

    期从定义起到程序结束。

    4:如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型。如下:

    1. #include <stdio.h>   
    2. char *returnStr()   
    3. {   
    4.     static char p[]="hello world!";   
    5.     return p;   
    6. }   
    7. int main()   
    8. {   
    9.     char *str;   
    10.      str=returnStr();   
    11.     printf("%s\n", str);   
    12.   
    13.     return 0;   
    14. }   

    5: 数组是不能作为函数的返回值的,原因是编译器把数组名认为是局部变量(数组)的地址。返回一个数组一般用返回指向这个数组的指针代替,而且这个指针不能指向一个自动数组,因为函数结束后自动数组被抛弃,但可以返回一个指向静态局部数组的指针,因为静态存储期是从对象定义到程序结束的。如下:

    1. int* func( void )  
    2. {  
    3.     static int a[10];  
    4.     ........  
    5.     return a;  
    6. }   

    6:返回指向堆内存的指针是可以的

    1. char *GetMemory3(int num)  
    2. {  
    3. char *p = (char *)malloc(sizeof(char) * num);  
    4. return p;  
    5. }  
    6. void Test3(void)  
    7. {  
    8. char *str = NULL;  
    9. str = GetMemory3(100);  
    10. strcpy(str, "hello");  
    11. cout<< str << endl;  
    12. free(str);  
    13. }  

    程序在运行的时候用 malloc 申请任意多少的内存,程序员自己负责在何时用 free释放内存。动态内存的生存期由程序员自己决定,使用非常灵活。
    展开全文
  • 不要返回指向局部变量指针

    千次阅读 2006-02-21 14:39:00
    有两种情况,函数会返回指向局部变量指针: 返回由malloc动态分配的内存指针。这种情况是合法的,但它假设调用者会释放动态分配的内存。在这种情况下通常会有另一个函数提供释放内存的功能。 返回指向局部变量的...
  • 返回指向局部变量指针才有问题, 函数退栈之后,局部变量消失, 指针将指向未知区域,所以出现问题。 返回局部变量的引用也是绝对不可以的。 引用只是变量的一个别名,变量本体都不存在了,引用当然也...
  • 如以上两个函数rref,rpot,分别返回指向局部变量的引用和指针。 如果在测试时,_tmain只有函数rref int &a = rref(); std::cout; 结果为ref11正确 如果_tmain只有函数rpot int *b = rpot()...
  • <p>Here is my go environment: <pre><code>[lorneli@localhost GoTest]$ go version go version go1.9 linux/amd64 </code></pre> <p>Here is my program: ...<pre><code>package main ...<p>I allocate a <code>...
  • 1.局部变量指针和局部指针变量是两个不同概念 2.局部变量在函数体结束后生命期也结束,它的指针(即它的地址)是无效变量的地址,所以函数不能返回这种地址值 3,局部指针变量在函数结束后生命期也结束,但它...
  • 下面一段程序: int main(void){ int *j=getPInt(); pad(); ... 我以为不会输出是100,因为getPInt函数... 我只是想验证返回指向局部变量指针不保险,可发现它很安全那! 小弟新手,言辞愚蠢之处还请指教。-.-
  • 在类中声明一个指针变量,并创建一个内部函数改变该指针变量的值。 (1).h文件 void readSettings(); QSettings *DialSettings; (2).cpp文件 void MainWindow::readSettings() { QSettings BasicSettings...
  • ------Java培训、Android培训、iOS培训、.Net培训、...(*p)是固定写法,代表指针变量p将来肯定是指向函数 // 左边的void:指针变量p指向的函数没有返回值 // 右边的():指针变量p指向的函数没有形参   int sum(int
  • 四、return返回指向局部变量指针或引用 在C语言中,局部变量的作用域只在函数内部,在函数返回后,局部变量的内存就会被释放。如果函数只是返回局部变量,那么这个局部变量会被复制一份传回被调用处。但是如果...
  • 1>子函数返回局部变量 例子1: 上面的简单程序,大家应该都知道应该会输出什么。是的,输出如下图: 引出的思考:子函数doubletimes()中的返回变量k是局部变量,返回到主函数后该变量超出了作用域,已经...
  • 局部变量在函数结束后释放,那么主函数为什么还能通过地址访问到内容呢? #include <stdio.h> int* fun() { int b = 6; int *p = &b; return p; } int main(void) { int ch; int *t = ...
  • 当使用定义函数返回指针变量时,我们要注意当返回的指针指的是局部变量的时候,这个指针指向是危险变量,因为局部变量在使用完后会被内存清空,因此这个指针指向的不定的。 如果要使局部变量的值在函数调用后不消失...
  • 我们大家都知道指针函数的返回指针不能指向函数内的自动变量,如果需要返回函数的内部变量的话,就需要将该变量声明为静态变量。为什么函数能够返回 静态变量的地址而不能返回局部自动变量的地址,到底什么样的对象...
  • C++里面说函数的返回值不可以返回指向局部变量指针。这个是绝对的么? char* getStr( char* str ) { char* p=0; p=str ; return p; } p是个局部变量,随着函数调用结束,它会直接销毁,如果指针...
  • 一道面试题引发的问题,首先要知道[]的优先级高于*,题目: char **p,a[6][8];...指针做形参,指针局部变量,数组做形参,数组做局部变量之类的题目非常容易考到,而且容易迷糊,得不断学习...
  • 如:int* 是一个指针变量类型指针变量和普通变量没有什么区别,指针32位四字节,里面保存的是一个内存空间的地址,就像一个整形变量int a, a就可以代表一个整数,一个指针变量int* p,p就可以代表一个地址数据,而*...
  • 想问一下,修改下面代码中的全局变量后,在打印pstr变量时,为什么在反汇编代码中看到callq 5e0 (栈检查失败),这是pstr的地址指向出现了问题吗,求大佬详细地解答 ``` #include #include #include ...
  • 一般的来说,函数是可以返回局部...因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,737
精华内容 694
关键字:

指针指向局部变量