字符串输出的几种情况 关于内存问题

来源:互联网 发布:ubuntu server 安装 编辑:程序博客网 时间:2024/05/19 05:31

http://blog.csdn.net/wae_gossip/article/details/8102614

http://bbs.elecfans.com/forum.php?mod=viewthread&tid=467133&extra=     不错

值传递不会传递动态内存,址传递才会传递动态内存。  注意:值传递(任何时候,参数传递都是拷贝形式);址传递是传递本身(内存),值传递传递替身。

#include<stdio.h>

#include<string.h>
#include<malloc.h>
void GetMemory(char *p, int num)


{

p = (char *)malloc(num);

}


void Test(void)


{


char *str = NULL;


GetMemory(str, 100);


strcpy(str, "hello");


printf(str);

}
int main()
{
Test();

}

运行出错,程序崩溃,char *p。而且像这种情况还会导致每次都泄露一块内存的危险。同级的只是值传递,不会改变数值的。当函数调用完以后,p指针(str)副本释放掉了。所以此时str仍然没有分配内存是个野指针。因为你的字符串是一个指针 然后你需要让str指向一个新分配的内存,如果直接传递char *的话 因为是函数调用 所以函数形参的p不是Test里面的str 只是一个复制了值的副本 所以对p操作无法修改str 而传递char **的话 p是str这个指针的地址 所以修改 *p 就可以修改str了
指针也是一个值。。传指针。。其实也是把指针地址复制过去一份。。。这里相当于把NULL值复制一份给p。。。p是局部变量。应该是str指针复制了一份传递给了p,然后执行完getmemory之后就释放掉了,test函数中的str并没有获得内存,str的值仍然是null吧。

由于函数是值传递,程序试图改变 str 的值,肯定不成功,getmemory执行完后,str还是NULL,所以在执行strcpy时,程序试图给NULL的指针赋值,会发生运行时错误!调用函数不能改变指针的值,当能改变指针变量所指向的值。。。。。

1.参数是值传递,(p和str指向同一块地方NULL)
2.但是函数又给参数p重新开辟空间,所以改变的是p指向的空间,str没变(还是指向NULL)。
3.所以因为str没有空间存放字符串,导致崩溃
如果你要改变实参的值,就传递实参的地址。这里指针是作为实参,所以要传递指针的地址。

上说程序str最后仍然为NULL

#include<stdio.h>
#include<string.h>
#include<malloc.h>
void GetMemory(char *p, int num)
{

p = (char *)malloc(num);

}
void Test(void)

{
char *str = NULL;
GetMemory(str, 100);
if (str == NULL)
{
printf("NULL\n");
}
//strcpy(str, "hello");
//printf(str);
}
int main()
{
Test();
}

输出NULL


#include<stdio.h>
#include<string.h>
#include<malloc.h>
void GetMemory(char *p, int num)




{


p = (char *)malloc(num);


}




void Test(void)




{




char *str = NULL;




GetMemory(str, 100);


printf("%p\n", str);
//strcpy(str, "hello");




//printf(str);


}
int main()
{
Test();
}
//out
00000000  //表示该指针为NULL
请按任意键继续. . .

http://zhidao.baidu.com/link?url=dSaNMGLWljNZIw7Zgrp5IhQzfneaqWiOxJthD7-AU-QuXjKkL3oBXMYF_87oU-Zus8gcjPBJ6LJneXUuFQR3A_

http://www.nowcoder.com/questionTerminal/681153b22f4d4622a7bf63cb6670aa23    good

2、#include<stdio.h>
#include<string.h>
#include<malloc.h>
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf("%p\n",str);
printf(str);
}
int main()
{
Test();
}
//out
001DF678
€ ? 请按任意键继续. . .     //每次运行的结果不同的

分析:可能是乱码。因为GetMemory 返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原来的内容已经被清除,新内容不可知。

3、#include<stdio.h>
#include<string.h>
#include<malloc.h>
void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
int main()
{
Test();
}
//out
hello请按任意键继续. . .

地址传递可以输出hello (2)内存泄漏

4、#include<stdio.h>
#include<string.h>
#include<malloc.h>
void Test(void)
{
char *str = (char *)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
strcpy(str, "world");
printf("%p\n", str);
printf(str);
}
}
int main()
{
Test();
}
//out
00682A98
world请按任意键继续. . .
分析:
篡改动态内存区的内容,后果难以预料,非常危险。
因为free(str); 之后,str 成为野指针,if(str != NULL)语句不起作用。

5.

char *GetMemory3(int num)

{

char *p = (char *)malloc(sizeof(char) * num);

return p;

}

void Test3(void)

{

char *str = NULL;

str = GetMemory3(100);

strcpy(str, "hello");

cout<< str << endl;

free(str);

}

请问运行Test 函数会有什么样的结果?
答:输出”hello”,因为是返回动态申请的内存,只要不释放内存,即调用free函数,就可以使用该段内存。

6.#include<stdio.h>
#include<iostream>
#include<string.h>
#include<malloc.h>
using namespace std;
char *GetString2(void)


{


char *p = "hello world";


return p;


}


void Test5(void)


{


char *str = NULL;


str = GetString2();
//strcpy(str, "hello world");//error 运行奔溃


cout << str << endl;


}
int main()
{
Test5();
}
//out
hello world
请按任意键继续. . .

答:函数Test5运行虽然不会出错,但是函数GetString2的设计概念却是错误的。因为GetString2内的hello world是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString2,它返回的始终是同一个只读的内存块。如果此时还想利用strcpy往str中写数据时,将出现错误。如strcpy(str,hello world)

0 0