malloc分配的数组太长

时间:2017-01-27 10:47:52

标签: 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个)其他字母最后。

2 个答案:

答案 0 :(得分: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 = '\0';  /* This was missing! */
  return result;
}

这也使用正确的size_t类型来处理字符串长度,并简化了内存分配。没有必要按sizeof (char)(始终为1)进行缩放,也不需要转换结果的类型。

答案 1 :(得分:0)

您必须为终止零保留空间,并将其从源字符串复制到目标阵列。此外,由于函数中的源字符串未更改,因此应使用限定符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