【问题标题】:Allocating memory for string pointers? [duplicate]为字符串指针分配内存? [复制]
【发布时间】:2020-10-06 22:01:34
【问题描述】:

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

【问题讨论】:

    标签: c c-strings string-literals function-definition tolower


    【解决方案1】:

    你给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); 
    

    【讨论】:

      【解决方案2】:

      至少有两个严重错误。

      第一个是您不能更改字符串文字。任何更改字符串文字的尝试都会导致未定义的行为。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-07
        • 2011-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-22
        • 1970-01-01
        相关资源
        最近更新 更多