简体   繁体   English

program.exe(c)(malloc)已停止工作

[英]program.exe(c) (malloc) has stopped working

Hi I wrote this code and it worked but in the end, "the program has stopped working" 嗨,我编写了这段代码,它起作用了,但最后,“程序已停止工作”

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

void main() 
{
    char *s;
    s=(char*)malloc(sizeof(char));
    printf("Enter a string:\n");
    gets(s);
    while (*s)
    {
        if (*s>= 65 && *s<=90)
            printf("%c",*s+32);
        else if(*s>=97 && *s<=122)
            printf("%c",*s-32);
        else
            printf("%c",*s);
        *s++;
    }
    free(s);
}

That code does not work, in fact it has undefined behavior. 该代码不起作用,实际上它具有未定义的行为。

This: 这个:

s = (char *) malloc(sizeof(char));

allocates 1 byte of storage, into which you then scan a string, thus very likely leading to buffer overflow. 分配1个字节的存储空间,然后在其中扫描字符串,这样很可能导致缓冲区溢出。 The buffer can only hold a single string, ie string of 0 characters before the terminator character at the end. 缓冲区只能包含一个字符串,即末尾字符前的0个字符的字符串。

You meant: 你的意思是:

s = malloc(128);

or something like that. 或类似的东西。

There's no need to cast, and sizeof (char) is always 1 so that doesn't add anything. 无需强制转换, sizeof (char)始终为1,因此不会添加任何内容。

Also, as more of a code review, magic numbers in code is generally considered a bad idea, instead write: 另外,作为代码审查的更多内容,代码中的幻数通常被认为是一个坏主意,而是这样写:

if (*s >= 'A' && *s <= 'Z')

or even better 甚至更好

if (isupper((unsigned int) *s))

to not hard-code a depdency on ASCII. 不硬编码ASCII上的依赖关系。

UPDATE Oh, and as pointed out in a comment, you can't change the value of s and then pass the changed value to free() , that is undefined behavior also. 更新哦,正如评论中指出的那样,您不能更改 s的值,然后将更改后的值传递给free() ,这也是未定义的行为。 The address passed to free() must be the same as the one you got back from malloc() . 传递给free()的地址必须与您从malloc()返回的地址相同。

Use a separate variable for the iteration: 使用单独的变量进行迭代:

char *p = s;

and only free() the original s . 并且仅free()原始s

Firstly, by s=(char*)malloc(sizeof(char)); 首先,通过s=(char*)malloc(sizeof(char)); you are allocating only 1 byte of memory for buffer. 您只为缓冲区分配了1个字节的内存。 Allocate enough memory to store the input. 分配足够的内存来存储输入。 Also avoid typecasting malloc() result. 还要避免类型转换malloc()结果。 Better version looks like 更好的版本看起来像

s = malloc(MAX * sizeof(*s));/* MAX is num of bytes you need to define */

Secondly don't use gets() use fgets() instead. 其次,不要使用gets() fgets()而是使用fgets() Read man 3 gets or check https://linux.die.net/man/3/gets 阅读man 3 gets或检查https://linux.die.net/man/3/gets

Finally use int main(void) { } instead of just main(){ } 最后使用int main(void) { }而不是main(){ }

And more importately when you do free(s) at that time s doesn't point to memory which was earlier allocated to it because of s++ so it may result error like 而且更重要的是,当您在那时执行free(s)时, s不会指向由于s++分配给它的内存,因此它可能会导致错误,例如

free(): invalid pointer: free():无效的指针:

So don't change s use s[row] while iterating OR you can assign s to other pointer and then you can do free(s) . 因此,请勿在迭代时更改s s[row] s使用,否则您可以将s分配给其他指针,然后可以执行free(s)

Complete code 完整的代码

int main() {
        char *s = NULL;
        int size = MAX*sizeof(*s);/*define MAX value, it is no of bytes need*/
        s = malloc(size);/* this is generic
                            sizeof(*s) works for any data type */
        printf("Enter a string:\n");
        fgets(s,size,stdin);/* use fgets() instead of gets() */
        int row = 0;
        while (s[row]!='\0') {
                if ( *(s+row) >= 65 && *(s+row) <= 90)
                        printf("%c",*(s+row) + 32);
                else if( *(s+row) >=97 && *(s+row) <= 122)
                        printf("%c",*(s+row) - 32);
                else
                        printf("%c",*(s+row));
                row++;
        }
        free(s);/* s still points to same location */
        return 0;
}

Also you can use isupper() instead of comparing each char ASCII value. 您也可以使用isupper()而不是比较每个char ASCII值。

This is wrong. 错了

s = (char*)malloc(sizeof(char));
printf("Enter a string:\n");
gets(s);

s = (char*)malloc(sizeof(char)); allocates 1 byte of memory. 分配1个字节的内存。 And then with gets(s); 然后用gets(s); you get a string, which will be Undefined Behavior. 您将得到一个字符串,该字符串将为“未定义行为”。

You have to changed it to 您必须将其更改为

s = malloc(MAX_LENGTH * sizeof(char));   //MAX_LENGTH is user defined

Additionally, you must check if malloc() returned anything. 此外,您必须检查malloc()返回任何内容。 If it returns NULL then it means no memory is allocated and all of the existing program will invoke undefined behavior. 如果返回NULL则意味着未分配内存,所有现有程序将调用未定义的行为。 Also, there is no need to cast the malloc result, so to further improve your code, you need to change it to, 另外,也无需malloc结果,因此,为了进一步改进代码,您需要将其更改为,

s = malloc(MAX_LENGTH * sizeof(char));
if(s == NULL)
{
    // Add error handling here
}

Also, 也,

void main()

isn't by the standard anymore, see This post which explains why. 不再是标准,请参阅这篇文章解释原因。 If you want to know what C11 standard states about it, then refer the standard here: Section 5.1.2.2.1 Program startup 如果要了解有关C11标准的内容,请在此处参考该标准: 5.1.2.2.1节,程序启动

So change it to, 因此将其更改为

int main(void)

You should make sure that you call free(s); 您应该确保拨打free(s);电话free(s); only if it was allocated. 仅在已分配的情况下。 As one of the comments below rightly indicates that free(NULL); 正如下面的评论之一正确地表明, free(NULL); is NOT a problem, but it also have no effect, so why call it anyway. 不是问题,但是也没有任何作用,所以为什么仍要这样称呼它。

Make s point to NULL again, but its irrelevant in this piece of code. 再次使s指向NULL ,但在这段代码中它与无关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM