首页 > 试题广场 >

下面代码会出现什么问题?

[问答题]
下面代码会出现什么问题?
char *GetMemory( void ) 
{  
 char p[] = "hello world";  
 return p;  
} 
void Test( void ) 
{  
 char *str = NULL;  
 str = GetMemory();  
 printf( str );  
} 
此题需要注意,若为题目所写,则会出现错误,因为数据为函数内局部变量,函数退出后,相应函数会被释放,但是若声明为char* p="Hello World!";返回指针会提示返回局部变量,但是能正常输出字符串,因为此时字符串存储在文字常量区,该区的生命周期为整个程序执行期间,p为指向常量区内存的地址,函数返回后p被销毁,但其所指向的内容被没有被销毁,类似与new出来的指针
发表于 2016-02-12 11:36:44 回复(6)
局部变量函数执行完毕销毁
发表于 2018-11-15 22:17:13 回复(0)
函数返回时,会用寄存器eax暂时存储函数返回值,回到被调函数处赋值。
对于返回类型是值类型,eax直接存储该值,回到主调函数中后赋值。
但是对于返回地址这一类的返回值,由于在被调函数结束就会自动释放掉分配给该函数的栈空间,因此eax若存储该地址是极不安全的,该地址空间随时会被其他函数或变量修改掉值,
所以对于需要返回地址的,要么把局部变量定义为static,要么让指针指向常量区的地址
在C#中,有out关键字可以修饰形参,从而解决这个隐患问题
发表于 2018-03-14 17:33:48 回复(0)
存在问题:
  • char p[] = "hello world";   return p; 数组p为函数的自动变量,存储在栈内存中,"hello world" 存储在文字存储区,数组p是 "hello world" 的一个副本,在函数返回后自动释放内存,副本也就消失了,而函数返回的p指向的内容变得不确定,文字存储区的 "hello world"未改变。
修改程序:
  • 可以修改为char *p = "hello world";   return p; 这里p直接指向文字存储区的"hello world",函数按值返回p存储的地址,所以有效。也可以修改为static char p[] = "hello world";   return p; static指出数组p为静态数组,函数结束也不会释放,所以有效。
发表于 2017-05-02 10:09:54 回复(0)
NWU头像 NWU
自动变量(即动态局部变量)属于动态存储类别,占动态存储区空间而不占静态存储空间,函数调用结束后立即释放。
发表于 2015-12-20 21:07:53 回复(0)
char p[] = "hello world"; 一个名为p的字符数组,把“H...”复制进去了,是一个局部变量。 char *p = "hello world"; 创建了一个指针,这个指针指向了一个常量的地址,这个地址的内容不是局部变量
发表于 2020-07-01 02:12:41 回复(0)
char p[]="hello world";相当于char p[12],strcpy(p," hello world" ).p是一个数组名,属于局部变量,存储在栈中, " hello world" 存储在文字存储区,数组p中存储的是 " hello world" 的一个副本,当函数结束,p被回收,副本也消失了(确切的说p指向的栈存储区被取消标记,可能随时被系统修改),而函数返回的p指向的内容也变得不确定,文字存储区的 " hello world" 未改变。可以这样修改: ①char* p= " hello world" ; return p; 这里p直接指向文字存储区的 " hello world" ,函数按值返回p存储的地址,所以有效。 ②static char p[]= " hello world" ; return p; static指出数组p为静态数组,函数结束也不会释放,所以有效。 以上两点,本人亲测。
发表于 2016-11-06 22:36:59 回复(25)
这里的p[]是一个数组,在函数内部,属于局部变量,存储在动态存储区,在函数调用时动态分配内存,调用完成之后销毁。可以修改为char *p = "Hello World"; return p; 利用指针进行寻址。或者static char p[] = "Hello world"; return p;静态变量存储在静态存储区,在程序结束后释放。
发表于 2018-07-22 16:38:18 回复(0)
不懂
发表于 2016-03-15 23:41:37 回复(1)
char p[] = "hello world";  
return p;  
的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。  
发表于 2015-10-28 17:59:07 回复(0)
我们写子函数的时候,定义一个int a=1,为什么同样为局部变量,可以return a
发表于 2016-03-11 08:38:51 回复(2)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* GetMemory(void) {
char* p = (char*)malloc(strlen("hello world") + 1);
strcpy(p, "hello world");
return p;
}

void Test(void) {
char* str = NULL;
str = GetMemory();
if (str != NULL) {
printf("%s\n", str);
free(str);
}
}

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

发表于 2024-10-21 00:50:11 回复(0)
链接:https://www.nowcoder.com/questionTerminal/13a4daacf9114ffea3bff132c8834db3?
来源:牛客网
以下代码有两个值得注意的地方:
1. str将成为一个野指针
在GetMemory函数中,创建了一个局部字符数组p[],并将字符串"hello world"复制到这个数组,之后试图返回指针p->p[0]
值得注意的是,当Test调用GetMemory时,p的值即p[0]的地址会成功的赋给str,但是由于数组p[]是一个局部变量,其在GetMemory结束调用时被释放,因此str所指向的区域的具体内容是未知的,访问它会导致未定义的行为
2. 在c++11标准中,字符串字面值被视为常量,因此无法赋值给指针变量,因此需要将p声明为const或使用strcpy函数赋值

解决方案:
static const char p[] = "hello world";
静态变量的生命周期在程序启动时分配内存,直到程序结束时释放,因此可以解决野指针的问题,但存在可能的并发访问问题
注意:避免返回指向局部变量的指针或局部变量的引用!
发表于 2023-09-13 10:57:44 回复(0)
char* GetMemory(void)
{
    int i = 0;
    char p[] = "hello world";
    char* ret;
    ret = (char*)malloc(sizeof(p));
    cout << sizeof(p) << endl;
    for (; p[i] !='\0'; i++)
    {
        *(ret + i) = p[i];
    }
    *(ret + i) = '\0';
    return ret;
}
void Test(void)
{
    char* str = NULL;
    str = GetMemory();
    printf(str);
}
发表于 2023-09-02 16:05:20 回复(0)
char p[]的生命期(自动存储期)随着函数退出而结束修改建议:static char p[] = “hello, world”;(块内作用域,但静态存储期)
发表于 2021-04-18 12:54:01 回复(0)

<p>数组p是局部变量,函数结束后内存会被释放</p>

编辑于 2020-12-26 11:42:25 回复(0)
<p>可以返回局部变量的值,也可以返回指向堆内存的地址,但是不能返回指向栈内存的地址,因为在调用结束后栈就会被清空</p>
发表于 2020-10-30 11:24:12 回复(0)
<p>函数中定义的形式是存放在栈中的局部变量 当函数模块结束后空间就会被回收释放 如果声明成char *p 或者static关键字就可以了</p>
发表于 2020-08-06 21:47:30 回复(0)
<p>所以 被调用函数分配的空间只能使用全局区或者堆区</p>
发表于 2020-07-25 17:02:25 回复(0)
<p>1.函数内申请在栈的空间,离开函数后就会收回</p>
发表于 2020-07-22 12:25:58 回复(0)