C语言编程遇到的问题

1.内存泄漏问题

问题代码1

 #include <stdio.h>
#include <stdlib.h> int main( int argc, char *argv[] )
{
unsigned int i = ;
char *str = "hello world!\r\n";
char *t = calloc( , sizeof( char ) ); while( str[i] )
{
*t++ = str[i];
i++;
}
t[i] = ;
printf( "%s", t );
printf( "%s", str );
free( t ); return ;
}

  上述代码要做的事情十分简单:将str字符指针指向的字符串复制到字符指针t指向的内存区域,t指向了一块200bytes大小的内存空间,为了保持str始终指向“hello world!\r\n”,没有对str变量本身进行增减操作。该程序运行的结果如下:

hello world!
Segmentation fault (core dumped)

  其实问题出在free()这里,即内存泄漏问题,传入该函数的指针变量必须指向之前分配好的地址,否则会产生内存释放失败。上述程序首先通过calloc()获得了一个内存地址,并放在字符指针变量t中,但是复制的时候t发生了变化,因此传入free()的参数并非calloc()的返回值,因此报错。

  一种解决方法是,使用一个指针变量记录分配得到的内存地址,但是并不操作它,只有在最后释放的时候作为free()的参数。

问题代码2

 #include <stdio.h>
#include <stdlib.h> int main( int argc, char *argv[] )
{
unsigned int i = ;
char *s = calloc( , sizeof( char ) );
char *t = s;
char *str = "abcdefghijklmn"; while( str[i] )
{
s[i] = str[i];
i++;
}
printf( "%s\n", t );
free( t ); return ;
}

  上述代码的功能也是实现字符串的复制,将str指向的“abcdefghijklmn”复制到s指向的内存中。运行后的错误如下:

abcdefghijklmn
*** glibc detected *** ./y: free(): invalid next size (fast): 0x084b0008 ***
======= Backtrace: =========
xxxxxxxxxxxxxxxxxxxxxx此处省略一些信息
======= Memory map: ========
xxxxxxxxxxxxxxxxxxxxxx此处省略一些信息
Aborted (core dumped)

  错误的原因是,calloc()只申请了5个字节大小的内存空间,而该程序将十几个字符都写入了该片内存,释放的时候检查到内存访问越界,因此报错,这里只要申请足够大的内存空间就可以了。

2. fflush()清空stdin数据流失败。

问题代码:

 #include <stdio.h>

 int main( int argc, char *argv[] )
{
char i, j, c; scanf( "%c", &i );
fflush( stdin );
scanf( "%c", &j ); printf( "%x %x\n", i, j ); return ;
}

  现象:程序期待两个字符,第二次执行scanf函数之前已经使用fflush清空输入缓冲区,但是输入一个字符之后,便输出结果,显示输入的字符以及一个十六进制数a。

  原因:fflush()函数没有起作用,第二个scanf获取到了换行符。

  解决方案:有必要的时候,清空输入缓冲区。清空的方案有两种:使用fflush()函数或者使用getchar()。

  fflush()用于清空缓冲区,多半指的是输出缓冲区,有些版本的函数库并不支持清空输入缓冲区,所以可移植性不强,这里使用的glibc就不支持,因此出错。

  移植性较强的代码实现是:while( ( c = getchar() ) != '\n' && c != EOF )

上一篇:Qt Creator下载和安装(详细教程)


下一篇:Nginx安装- CentOS7