1. 程式人生 > >字串常量的BUG

字串常量的BUG

當我們定義了一個字串常量並且用一個指標指向它,這時有一個不容易發現的嚴重BUG。

如下面這樣定義:

    const char *p = "s a ";
    printf("n = [%d]\n", my_run(a));
編譯會在這樣存放常量:s a n = [%d]\n'\0'

這裡可以發現一個BUG,就是*p指向的字串沒有加上'\0',本來應該是這樣:s a '\0'n = [%d]\n'\0'

這樣會帶來一些麻煩,就如下面的程式。

#include <stdio.h>
#include <stdlib.h>

int my_run(const char *input_str)
{
	const char *str_p = input_str;
	int n = 0;
	for(; str_p != '\0'; str_p++)
	{
		if((*str_p != 32) && (*(str_p + 1) == '\0')){
			++n;
			break;
		}
		if(*str_p == 32)
		{
			printf("n = [  %c  ]\n",* str_p );
			++n;
		}else{
			printf("n = [  %c  ]\n",* str_p );
			}
	}
	return n;
}

int  main(void)
{
	const char *a = "s a ";
	printf("n = [%d]\n", my_run(a));

	return 0;
}

執行結果:

n = [  s  ]
n = [     ]
n = [  a  ]
n = [     ]
n = [    ]
n = [  n  ]
n = [     ]
n = [  =  ]
n = [     ]
n = [  [  ]
n = [  %  ]
n = [  d  ]
n = [  ]  ]
n = [5]

但是當我們在定義字串是不是以空格結尾就沒問題,下面的程式可以證明

#include <stdio.h>
#include <stdlib.h>

int my_run(const char *input_str)
{
	const char *str_p = input_str;
	int n = 0;
	for(; str_p != '\0'; str_p++)
	{
		if((*str_p != 32) && (*(str_p + 1) == '\0')){
			++n;
			break;
		}
		if(*str_p == 32)
		{
			printf("n = [  %c  ]\n",* str_p );
			++n;
		}else{
			printf("n = [  %c  ]\n",* str_p );
			}
	}
	return n;
}

int  main(void)
{
	const char *a = "s a a";
	printf("n = [%d]\n", my_run(a));

	return 0;
}

執行結果:

n = [  s  ]
n = [     ]
n = [  a  ]
n = [     ]
n = [3]

總結:

這裡的BUG就是編譯器的問題,只有我們自己來避免這個BUG。