确定数组的长度以提高内存效率

pra*_*dha 1 c memory

用C语言编写一个函数:

  • 将存储在字符串中的句子作为其唯一参数(例如,"这是一个短句子".).
  • 返回一个字符串,该字符串由每个单词中的字符数(包括标点符号)组成,空格分隔数字.(例如,"4 2 1 5 9").

我写了以下程序:

 int main()    
    {  
            char* output;  
            char *input = "My name is Pranay Godha";  
            output = numChar(input);  
            printf("output : %s",output);  
            getch();  
            return 0;  
    }  


char* numChar(char* str)   
{   
        int len = strlen(str);  
    char* output = (char*)malloc(sizeof(char)*len);   
    char* out = output;  
    int count = 0;  

    while(*str != '\0')  
    {
        if(*str != ' ' )
        {
            count++;
        }
        else
        {

            *output = count+'0';
            output++;
            *output = ' ';
            output++;
            count = 0;

         }
         str++;
   }  
   *output = count+'0';  
   output++;  
   *output = '\0';  
   return out;  
}  
Run Code Online (Sandbox Code Playgroud)

我只是想知道我正在len为输出字符串分配内存量,我觉得这比我应该分配的更多,因此有一些内存浪费.你能告诉我我能做些什么来提高内存效率吗?

sel*_*bie 6

我看到很多小虫子.如果我是你的导师,我会把你的解决方案评为"C-".这里有一些关于如何将其变成"A +"的提示.

 char* output = (char*)malloc(sizeof(char)*len); 
Run Code Online (Sandbox Code Playgroud)

上述两个主要问题.首先,你忘了"释放"你分配的内存.但这很容易被原谅.

实际的真实错误.如果你的字符串只有1个字符长(例如"x"),你只能分配一个字节.但是您可能需要将两个字节复制到字符串缓冲区中.一个'1'后跟一个空终止'\ 0'.最后一个字节被复制到无效的内存中.:(

另一个错误:

*output = count+'0'; 
Run Code Online (Sandbox Code Playgroud)

当"count"大于9时会发生什么?如果"count"为10,那么*output将被赋予冒号,而不是"10".

首先编写一个只计算字符串中单词数的函数.将此函数的结果分配给变量调用num_of_words.

因为你可能有超过9个字符的单词,所以有些单词将有两个或更多的数字输出.而且你需要考虑每个数字之间的"空间".并且不要忘记尾随的"空"字节.

如果你考虑一个1字节无符号整数在字符串表示('0'..'255')中最多可以有3个字符不包括空字符或负数的情况,那么sizeof(int)*3是对整数表示的最大字符串长度的合理估计(不包括空字符).因此,您需要分配的内存量是:

 num_of_words = countWords(str);
 num_of_spaces = (num_of_words > 0) ? (num_of_words - 1) : 0;
 output = malloc(num_of_spaces + sizeof(int)*3*num_of_words + 1); // +1 for null char
Run Code Online (Sandbox Code Playgroud)

所以这是一个相当不错的内存分配估计,但它肯定会在所有场景中分配足够的内存.

我认为你的程序中还有其他一些错误.首先,如果每个单词之间有多个空格,例如

"my     gosh"
Run Code Online (Sandbox Code Playgroud)

我希望你的程序打印"2 4".但是您的代码会打印其他内容.如果字符串中有前导或尾随空格,则可能存在其他错误.并且内存分配估计不考虑在这些情况下插入的额外垃圾字符.

更新:

鉴于你坚持并试图在下面的答案中找到更好的解决方案,我会给你一个提示.我编写了一个函数,用于打印字符串中所有单词的长度.它实际上并没有分配字符串.它只是打印它 - 好像有人在你的函数要返回的字符串上调用了"printf".你的工作是推断这个函数的工作原理 - 然后修改它以返回一个新的字符串(包含所有单词的整数长度),而不是只打印它.我建议你修改这个函数中的主循环,以保持字数的运行总和.然后分配一个size =(word_count*4*sizeof(int)+ 1)的缓冲区.然后再次循环输入字符串,将每个单词的长度附加到您分配的缓冲区中.祝好运.

void PrintLengthOfWordsInString(const char* str)
{
    if ((str == NULL) || (*str == '\0'))
    {
        return;
    }

    while (*str)
    {
        int count = 0;

        // consume leading white space
        while ((*str) && (*str == ' '))
        {
            str++;
        }

        // count the number of consecutive non-space chars
        while ((*str) && (*str != ' '))
        {
            count++;
            str++;
        }

        if (count > 0)
        {
            printf("%d ", count);
        }
    }
    printf("\n");
}
Run Code Online (Sandbox Code Playgroud)