首页 行业资讯 宠物日常 宠物养护 宠物健康 宠物故事

打开软件提示“invalid pointer operation”怎么解决 重装后不久又有此现象是怎么回事

发布网友

我来回答

2个回答

热心网友

无效指针操作。应该是程序中处理内存操作出错。可能是由于程序本身的bug (大几率) 或者由于机器本身内存不兼容导致 (小几率)。

热心网友

嵌入式Linux开发《C语言专题(五:(3)实用的内存函数6)》

嵌入式软硬件开发
2019-02-12 · 优质教育领域创作者

在文章嵌入式Linux开发《C语言专题(五:(3)实用的内存函数4)》嵌入式Linux开发《C语言专题(五:(3)实用的内存函数5)》中对C语言中内存操作函数做了部分介绍。最后留了与malloc&free有关的几个问题,这篇文章将用代码和结果来分析这些问题,如下所示:

1)malloc(0)真的是申请0空间吗?malloc(100)呢?

2)malloc 多次free 1次 或者malloc 1次 free多次?

3)没有检查内存分配是否成功?

4)使用申请的动态内存时超出了申请的内存边界?

5)释放一部分内存空间?

6)试图访问已经释放的内存?

(1)malloc(0)真的是申请0空间吗?malloc(100)呢?

代码演示:
#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h>
#define NUMBER 4
//演示malloc(0)和malloc(100)
int main(int argc, char** argv)
{
int i = 0;
int *p = NULL;
//第一步:申请内存空间
p = (int *)malloc(0);
//p = (int *)malloc(100);
//第二步:检查返回值
if(NULL == p)
{
printf("申请内存空间出错");
//如果出错,退出整个进程
exit(-1);
}
printf("申请的地址为 = %p \n", p);
//第三步:暂时先不使用内存空间
//第四步:释放内存空间
free(p);
p = NULL;

return 0;
}

运行结果:

lz@ubuntu:~/share$ ./memory

申请的地址为 = 0x98ab008

lz@ubuntu:~/share$ ./memory

申请的地址为 = 0x86c5008

lz@ubuntu:~/share$ ./memory

申请的地址为 = 0x8534008
分析结果:malloc(0)和malloc(100)返回的结果不为NULL,malloc(0)的结果是一个合法的地址,并且每次返回的地址值不一样。

那么是否malloc(0)的地址可以使用?

代码演示:
#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h>
//当NUMBER的值小于等于3时,不会出错,否认就会出错,验证malloc(0)返回未必是空地址
#define NUMBER 4
//演示malloc(0)
int main(int argc, char** argv)
{
int i = 0;
int *p = NULL;
//第一步:申请内存空间
p = (int *)malloc(0);
//第二步:检查返回值
if(NULL == p)
{
printf("申请内存空间出错");
//如果出错,退出整个进程
exit(-1);
}
printf("申请的地址为 = %p \n", p);
//第三步:使用内存空间
for(i=0; i<NUMBER; i++)
{
//将所申请的内存空间赋值为0
p[i] = 0;
printf("p[%d] = %d \n", i, p[i]);
}
//第四步:释放内存空间
free(p);
p = NULL;

return 0;
}

运行结果:

lz@ubuntu:~/share$ ./memory

申请的地址为 = 0x857b008

p[0] = 0

p[1] = 0

p[2] = 0

p[3] = 0

*** Error in `./memory': free(): invalid next size (fast): 0x0857b008 ***

Aborted (core mped)
分析结果:当NUMBER大于等于4时,在 free()时出现段错误,小于4时,正确。因此,在实际的研发时不要使用malloc(0),这个没有意义。 官方解释是当malloc(0)也可能返回NULL或者是一个独特的指针,这个指针随后传递给free。

(int *)malloc(100)一定是申请25个整型数据个数吗?

答:p=(int *)malloc(100)申请的整型数据个数并不能确定是25个,因为在不同的系统中int所占的字节数不同。如果是在32位操作系统中,那么就是,如果是在位操作系统中就不是了。如果想要申请存储25个整型数据,为了可移植性,可使用p=(int*)malloc(sizeof(int)*25)。注意sizeof的使用方法。

(2)malloc 多次free 1次 或者malloc 1次 free多次?

代码演示:
#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h>
#define NUMBER 4
//演示malloc一次,free多次
int main(int argc, char** argv)
{
int i = 0;
int *p = NULL;
//第一步:申请内存空间
p = (int *)malloc(sizeof(int) * NUMBER);
//第二步:检查返回值
if(NULL == p)
{
printf("申请内存空间出错");
//如果出错,退出整个进程
exit(-1);
}
printf("申请的地址为 = %p \n", p);
//第三步:使用内存空间
for(i=0; i<NUMBER; i++)
{
//将所申请的内存空间赋值为0
p[i] = 0;
printf("p[%d] = %d \n", i, p[i]);
}
//第四步:释放内存空间
free(p);
free(p);//第二次free出错
p = NULL;
return 0;
}

运行结果:

lz@ubuntu:~/share$ ./memory

申请的地址为 = 0x9d2c008

p[0] = 0

p[1] = 0

p[2] = 0

p[3] = 0

*** Error in `./memory': double free or corruption (fasttop): 0x09d2c008 ***

Aborted (core mped)
分析结果:错误显示是2次free导致的段错误。因为第一次已经将返回的地址及申请的内存空间释放了,此时p就是异常内存地址,再次释放当然会出错。因此,在实际操作时申请一次释放一次就可以。

只malloc不free会怎样?

代码演示:
#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h>
#define NUMBER 100000000
//演示申请内存空间,但是不free
int main(int argc, char** argv)
{
int *p = NULL;
//申请内存空间
while(1)
{
p = (int *)malloc(sizeof(int) * NUMBER);
}

return 0;
}
如果申请的内存空间没有得到有效释放,那么总有一天堆会被撑爆(因为堆空间大小是一定的),导致系统终止运行。这种现象称之为内存泄漏即动态申请内存之后,当不再使用时没有释放这些内存,导致系统的内存被一点一点的消耗 最终导致系统崩溃,之后只能通过重启系统解决。所以也就告诫我们当不使用内存时,一定要记得释放内存,以便于后续重新被分配使用。

(3)没有检查内存分配是否成功?

答:在使用malloc时一定要检查返回值是否为NULL,如果返回值为NULL,而没有检查,会导致直接使用返回值为NULL的地址空间,导致出现Segmentation fault (core mped)段错误,因为我们访问了异常空间。

(4)使用申请的动态内存时超出了申请的内存边界?

代码演示:
#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h>
//需要10个整数但实际只申请4个
#define NUMBER 10
//演示使用申请的动态内存时超出了申请的内存边界
int main(int argc, char** argv)
{
int i = 0;
int *p = NULL;
//第一步:申请内存空间
p = (int *)malloc(sizeof(int)*4);
//第二步:检查返回值
if(NULL == p)
{
printf("申请内存空间出错");
//如果出错,退出整个进程
exit(-1);
}
printf("申请的地址为 = %p \n", p);
//第三步:使用内存空间
for(i=0; i<NUMBER; i++)
{
//将所申请的内存空间赋值为0
p[i] = 0;
printf("p[%d] = %d \n", i, p[i]);
}
//第四步:释放内存空间
free(p);
p = NULL;

return 0;
}

运行结果:

lz@ubuntu:~/share$ ./memory

申请的地址为 = 0x90bf008

p[0] = 0

p[1] = 0

p[2] = 0

p[3] = 0

p[4] = 0

p[5] = 0

p[6] = 0

p[7] = 0

p[8] = 0

p[9] = 0

*** Error in `./memory': free(): invalid next size (fast): 0x090bf008 ***

Aborted (core mped)
分析结果:段错误 虽然申请4个空间但是可以访问10个空间,虽然有时候可以访问超过申请的内存空间,但是这样做可能无意间冲掉原来的内存空间的值,所以最好不要这样做。

(5)释放一部分内存空间?

代码演示:
#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h>
#define NUMBER 4
//演示释放一部分内存空间
int main(int argc, char** argv)
{
int i = 0;
int *p = NULL;
//第一步:申请内存空间
p = (int *)malloc(sizeof(int) * NUMBER);
//第二步:检查返回值
if(NULL == p)
{
printf("申请内存空间出错");
//如果出错,退出整个进程
exit(-1);
}
printf("申请的地址为 = %p \n", p);
//第三步:使用内存空间
for(i=0; i<NUMBER; i++)
{
//将所申请的内存空间赋值为0
p[i] = 0;
printf("p[%d] = %d \n", i, p[i]);
}
//第四步:释放内存空间
free(p+1);//释放一部分内存空间 出错
p = NULL;
return 0;
}

运行结果:

lz@ubuntu:~/share$ ./memory

申请的地址为 = 0x9112008

p[0] = 0

p[1] = 0

p[2] = 0

p[3] = 0

*** Error in `./memory': free(): invalid pointer: 0x0911200c ***

Aborted (core mped)
分析结果:段错误,申请的起始地址p是 0x9112008 p+1的地址是0x0911200c不是申请的起始地址,所以出错。

(6)试图访问已经释放的内存?

#include <stdio.h>
//一定要加上操作头文件
#include <stdlib.h>
#define NUMBER 4
//演示试图访问已经释放的内存
int main(int argc, char** argv)
{
int i = 0;
int *p = NULL;
//第一步:申请内存空间
p = (int *)malloc(sizeof(int) * NUMBER);
//第二步:检查返回值
if(NULL == p)
{
printf("申请内存空间出错");
//如果出错,退出整个进程
exit(-1);
}
//第三步:使用内存空间
for(i=0; i<NUMBER; i++)
{
//将所申请的内存空间赋值为2
p[i] = 2;
printf("p[%d] = %d \n", i, p[i]);
}
//第四步:释放内存空间
free(p);
p[3] = 1;//试图访问已经释放的内存
printf("p[3] = %d \n", p[i]); //为0 既不是1也不是2
p = NULL; //放在p[3] = 1;后面不会出现段错误,放在前面会出现

return 0;
}

运行结果:

lz@ubuntu:~/share$ ./memory

申请的地址为 = 0x9c33008

p[0] = 2

p[1] = 2

p[2] = 2

p[3] = 2

p[3] = 0
分析结果:没有达到使得p[3] = 1,因为原来申请的地址空间已经被释放了。也不是原来的值2,而是0,表示此时访问原来地址的内容已经无效了。所以我们不要访问已经释放申请的内存空间的值。

总结:把这些问题通过敲代码分析结果搞明白,就可以搞定与malloc&free有关的问题。

未完待续,后续继续更新内存函数具体用法...

更多精彩内容可以关注此头条号:嵌入式软硬件开发 喜欢的话大家可以“评论”,“转发”、“点赞”或者“收藏”,感谢大家。相互交流,共同成长。

搜索
初学编程100个代码
十大编程代码大全
c语言编程新手入门教程
嵌入式编程入门教学
自己学c语言有前途吗
c语言知识点总结归纳

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com