C语言 malloc 分配的数组太长



我正在尝试通过包含的代码复制字符串(并使其内容大写):

char* foo(char* word)
{
   int wordLength = strlen(word);
   char* result = (char*)malloc(wordLength * sizeof(char));
   for (int i = 0; i < wordLength; ++i)
      result[i] = toupper(word[i]);
   return result;
}

变量wordLength包含正确的数字(word中确切的字母数),但是result字符串比字符串长word并且末尾包含很少(大约 4 个)附加字母。

您无法终止复制。

请记住,C 字符串是以数值为 0 的字符结尾的字符数组。

更正的代码:

char * foo(const char *word)
{
  const size_t len = strlen(word);
  char *result = malloc(len + 1);
  char *put = result;
  while(len--)
   *put++ = toupper(*word++);
  *put = '';  /* This was missing! */
  return result;
}

这也使用正确的size_t类型来处理字符串长度,并简化内存分配。无需按 sizeof (char) 缩放(始终为 1),也无需强制转换结果的类型。

您必须为终止零保留空间,并将其从源字符串复制到目标数组。此外,由于源字符串在函数中没有更改,因此应使用限定符 const 进行声明。

该函数可以如下所示

char* foo( const char* word )
{
    char* result = ( char* )malloc( strlen( word ) + 1 );
    return strcpy( result, word );
}

考虑到有 POSIX 函数strdup执行相同的任务。

如果在复制字符串的同时需要将其转换为大写,则该函数可以如下所示

char* foo( const char *word )
{
    char* result = ( char* )malloc( strlen( word ) + 1 );
    char *p = result;
    do 
    {
        *p++ = toupper( ( unsigned char )*word );
    } while ( *word++ );
    return result;
}

或者可以使用 while 循环而不是 do-while 循环来编写函数。例如

char* foo( const char *word )
{
    char* result = ( char* )malloc( strlen( word ) + 1 );
    char *p = result;
    while ( ( *p++ = toupper( ( unsigned char )*word++ ) ) ); 
    return result;
}

这是一个演示程序

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char* foo( const char *word )
{
    char* result = ( char* )malloc( strlen( word ) + 1 );
    char *p = result;
    while ( ( *p++ = toupper( ( unsigned char )*word++ ) ) ); 
    return result;
}
int main( void ) 
{
    char *s = foo( "hello world" );
    puts( s );
    free( s );
    return 0;
}

它的输出是

HELLO WORLD

最新更新