为字符串指针分配内存?

问题描述

我在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 );