问题描述
我在C语言的一些基本知识上苦苦挣扎。我尝试编译该程序,结果出现了Signal 11错误。我知道这与内存分配有关,但是我不确定如何正确使用malloc()
来完成这项工作。有人可以帮忙吗?
{
char *string = "Lol";
convert_lower(string);
printf("%s\n",string);
return 0;
}
char *convert_lower(char *word) {
for ( ; *word; ++word) *word = tolower((char)*word); // J.F. Sebastian
return word;
}
解决方法
您正在为convert_lower()
提供指向字符串文字的指针,因此它将尝试修改只读存储器。这就是为什么会出现运行时错误。
您需要先对字符串文字的数据进行可写复制,然后才能对其进行修改,例如:
char *literal = "Lol";
char *string = malloc(strlen(literal)+1);
strcpy(string,literal);
convert_lower(string);
printf("%s\n",string);
free(string);
可以使用strdup()
来简化,它将为您处理分配和复制:
char *string = strdup("Lol");
convert_lower(string);
printf("%s\n",string);
free(string);
然后,您可以通过根本不分配任何动态内存来进一步简化此操作:
char string[] = "Lol";
convert_lower(string);
printf("%s\n",string);
,
至少有两个严重错误。
第一个是您不能更改字符串文字。任何更改字符串文字的尝试都会导致未定义的行为。
char *string = "Lol";
convert_lower(string);
第二个是在函数中更改了传递的指针。因此该函数将返回一个指向终止零的指针,而不是指向字符串的开头。
而不是强制转换为char
tolower((char)*word)
您需要转换为未签名的字符
tolower( (unsigned char)*word)
可以像这样定义函数
char * convert_lower( char *word )
{
for ( char *p = word; *p; ++p )
{
*p = tolower( ( unsigned char )*p );
}
return word;
}
并称呼为
char string[] = "Lol";
puts( convert_lower(string) );
如果要复制原始字符串,将所有字符都转换为小写,则该函数可以采用以下方式
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
//...
char * convert_lower( const char *word )
{
char *result = malloc( strlen( word ) + 1 );
if ( result != NULL )
{
char *p = result;
while ( ( *p++ = tolower( ( unsigned char )*word++ ) ) != '\0' );
}
return result;
}
该函数可以像
那样调用char *string = "Lol";
char *lower_case_string = convert_lower( string );
if ( lower_case_string != NULL ) puts( lower_case_string );
free( lower_case_string );