C中的内存分配 - 缩略语:)

时间:2018-01-15 12:38:06

标签: c

Example of the input/output

请参阅下面的代码。用户应该输入一个句子,代码应该返回句子的首字母缩略词。

但是,当我分配* str并将N定义为1时。

"三个字母的首字母缩略词" >>应该是>> " T"

实时,"三个字母的首字母缩略词" >>是>> " TLA"

这没有意义。 请解释为什么会发生这种情况。

#include <stdio.h>
#include <stdlib.h>

#define N 1
#define M 35

char *acronyms (char *st,  char *sentence);

int main()
{

char *str=(char*)(malloc(N*sizeof(char)));
char *sen=(char*)(malloc(M*sizeof(char)));

printf("enter... ");
gets(sen);
puts(acronyms(str, sen));

free(str);
free(sen);
    return 0;
}


char *acronyms (char *st,  char *sentence)
{
     char *p = st;
     char *q = sentence;

     if (*q !=' ') {
            *p =*q;
            p++;
     }

     while (*(q+1)) {
         if (*q==' '  &&  *(q+1)!= ' ') {
             *p = *(q+1);
             p++;
         }

        q++;
     }
     *p='\0';
     return st;
}

4 个答案:

答案 0 :(得分:1)

首先,您不应该使用gets()。为什么??检查this

您只将1字节的内存分配给str

char *str=(char*)(malloc(N*sizeof(char)));

并且在函数acronyms()中,您正在编写超出分配的内存。这是undefined behavior

要获得输入句子的首字母缩写词,您可以执行以下操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define STR_LEN 100

char *acronyms (char *pstr,  char *str_acronym);

int main(void) {

    char input_str[STR_LEN];
    char *sen = NULL;

    printf ("Enter:\n");
    fgets (input_str, STR_LEN, stdin);

    sen = malloc (strlen(input_str) + 1);
    if (sen == NULL) {
            perror ("Failed to allocate memory");
            return -1;
    }

    puts (acronyms(input_str, sen));

    free(sen);

    return 0;
}

char * acronyms(char *pstr,  char *str_acronym)
{
    int count = 0, add = 1;

    for (int i = 0; pstr[i] != '\0'; i++) {
            if (isspace(pstr[i])) {
                    add = 1;
                    continue;
            }
            if (add) {
                    str_acronym[count] = pstr[i];
                    count++;
                    add = 0;
            }
    }
    str_acronym[count] = '\0';

    return str_acronym;
}

答案 1 :(得分:1)

代码中存在一些问题:

1)仅为字符串str分配一个字节:

#define N 1
char *str=(char*)(malloc(N*sizeof(char)));

2)使用gets(sen)代替fgets(sen,M+1,stdin);

3)char *acronyms (char *st, char *sentence) 有很多问题的逻辑。无法识别字符串的结尾,' '可能存在也可能不存在:

 if (*q !=' ') {
        *p =*q;
        p++;
 }

答案 2 :(得分:1)

乍一看这看起来似乎并不令人满意,但是一旦你理解了这5个概念所指出的基本原则(每个概念都有例子),这个和其他类似的任务看起来会简单得多。

做你正在尝试的事情的必要步骤:

1)了解控制台用户输入技术( Good example here
2)理解字符串的定义( Good definition,explanation here 。)
3)了解[c][m]alloc(...) Good discussion here... ...)的使用情况 3a)......以及何时使用它。或不。 ( heap vs. stack memory
4)理解字符串解析技术。 ( ex 1 ex 2 ex 3
5)了解合法但不明智的技巧,例如使用 gets in general

这些通常是适用的技术,对包括用户输入和字符串操作在内的许多任务非常有用,但对于引用优秀的C书来提供基础知识的必要基础并不是一个很好的替代。

答案 3 :(得分:0)

未定义行为世界中的惠康!当您使用数组中的数据时,任何事情都可能发生包括预期结果。这就是这里发生的事情:为str分配1个单字节,并写入5 {'h', 'a, 'n', 'd', '\0'}。 [联合国]幸运的是,在较低的级别,您似乎只会覆盖未使用的内存,并实际获得结果。

就像它是UB一样,你不能依赖它,并且在不同的环境中编译的相同源可能是SEGFAULT或者没有打印任何完全相同的输入。

正如你在评论don't use gets

中所说的那样