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

时间:2018-04-20 08:38:17

标签: c

您好,我写了这段代码但它最终有效,“该程序已停止工作”

#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);
}

3 个答案:

答案 0 :(得分:4)

该代码不起作用,实际上它有未定义的行为。

此:

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

分配1个字节的存储空间,然后扫描一个字符串,因此很可能导致缓冲区溢出。缓冲区只能保存一个字符串,即结尾处终结符之前的0个字符的字符串。

你的意思是:

s = malloc(128);

或类似的东西。

无需投射,sizeof (char)始终为1,因此不会添加任何内容。

此外,作为更多的代码审查,代码中的幻数通常被认为是一个坏主意,而是写:

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

甚至更好

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

不对ASCII上的依赖进行硬编码。

更新哦,正如评论中指出的那样,您无法更改 s的值,然后将更改后的值传递给free(),这也是未定义的行为。传递给free()的地址必须与您从malloc()返回的地址相同。

为迭代使用单独的变量:

char *p = s;

且仅free()原始s

答案 1 :(得分:1)

首先,通过s=(char*)malloc(sizeof(char));,您只为缓冲区分配1个字节的内存。分配足够的内存来存储输入。还要避免类型转换malloc()结果。更好的版本看起来像

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

其次,请勿使用gets()使用fgets()。阅读man 3 gets或查看https://linux.die.net/man/3/gets

最后使用int main(void) { }而不是main(){ }

当你执行free(s) s时,s++更加重要而不是指向因s而早先分配给它的内存,因此可能会导致错误,如

  

free():指针无效:

因此,在迭代时不要更改s[row]使用s或者您可以将free(s)分配给其他指针,然后您可以执行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; }

完整代码

isupper()

此外,您可以使用mkfifo my_named_pipe 而不是比较每个char ASCII值。

答案 2 :(得分:0)

这是错误的。

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

s = (char*)malloc(sizeof(char));分配1个字节的内存。然后用 gets(s);你得到一个字符串,它将是Undefined Behavior。

您必须将其更改为

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

此外,您必须检查malloc()是否返回任何内容。如果它返回NULL,则表示没有分配内存,并且所有现有程序都将调用未定义的行为。 此外,无需转换malloc结果,因此为了进一步改进您的代码,您需要将其更改为,

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

此外,

void main()

不再符合标准,请参阅This post解释原因。如果您想知道C11标准对此有何规定,请参考此处的标准:Section 5.1.2.2.1 Program startup

所以改成它,

int main(void)

您应确保仅在分配free(s);时才调用free(NULL);。正如下面的评论之一正确地指出s不是问题,但它也没有效果,所以为什么还要调用它。

NULL再次指向 SELECT DB.OrganisationPersonnel.OrganisationID , DB.OrganisationPersonnel.PersonnelID AS [if not ProductPAID =5] , DB.Title.Name , DB.Person.FirstName , DB.Person.MiddleName , DB.Person.LastName , DB.OrganisationPersonnel.ActualJobTitle , DB.Phone.Number AS [if ProductPAID <3] , DB.Email.Email AS [if ProductPAID =2 or 5] , DB.Person.ProductDPAID , DB.ProductDPA.Name FROM (((DB.OrganisationPersonnel INNER JOIN (DB.Person INNER JOIN DB.Title ON DB.Person.TitleID = DB.Title.ID) ON DB.OrganisationPersonnel.PersonnelID = DB.Person.ID) LEFT JOIN DB.Phone ON DB.OrganisationPersonnel.PhoneID = DB.Phone.ID) LEFT JOIN DB.Email ON DB.OrganisationPersonnel.EmailID = DB.Email.ID) INNER JOIN DB.ProductDPA ON DB.Person.ProductDPAID = DB.ProductDPA.ID WHERE (((DB.OrganisationPersonnel.EmployedToDate) Is Null)) ORDER BY DB.OrganisationPersonnel.OrganisationID; ,但在此段代码中无关紧要。