简体   繁体   English

For循环卡在C(cygwin)的函数调用中,非常奇怪的行为我无法理解

[英]For loop gets stuck in a function call in C (cygwin), very weird behavior i couldn't understand

I have this function someoneDidSomething() , it's meant to generate a random phrase like "Mandy loved Jesus!" 我有这个函数someoneDidSomething() ,它的意思是生成一个随机短语,例如“曼迪爱耶稣!” for example. 例如。

The problem is, when I call it only one time and exit the program it works just fine. 问题是,当我只调用它一次并退出程序时,它运行正常。 Even if i call the program few times repeatedly. 即使我反复调用该程序几次。 But when I call it in a loop the output looks like the image below. 但是,当我在一个循环中调用它时,输出如下图所示。

PS: After some time I get a segmentation fault. PS:一段时间后,我遇到了细分错误。

I'm pretty much confused :D - this makes no sense. 我非常困惑:D-这没有任何意义。

void main ()
{
    for (int i = 0; i <= 500; i++)
    {
        char message[255];
        strcpy (message, someoneDidSomething());
        printf ("Because %s\n", message);
        sleep (1);
    }
}

char* someoneDidSomething()
{
    static char message[255];
    strcat (message, getPerson());
    strcat (message, " ");
    strcat (message, getVerb());
    strcat (message, " ");
    strcat (message, getSomething());
    strcat (message, ".");
    return message;
}

Called one time output: 称为一次输出:

Because Mandy loved Jesus.

Called in a for loop: 在for循环中调用:

Because Mandy loved Jesus.Hammond felt the World.Ashlynn knew Jesus.

here: 这里:

static char message[255];
strcat (message, getPerson());

the first time it works because global memory ( static is zeroed in most systems, although adding a = {0}; doesn't hurt), so strcat acts like strcpy . 第一次工作是因为全局内存(大多数系统中的static内存都为零,尽管添加a = {0};不会造成伤害),所以strcat行为类似于strcpy

But subsequent calls keep the value in message . 但是随后的调用将值保留在message message grows and grows, so not the result you want, and after a while, buffer overflows triggers a segmentation fault. message不断增长,因此不是您想要的结果,一段时间后,缓冲区溢出会触发分段错误。

You need strcpy for the first step. 第一步需要strcpy

static char message[255];
strcpy (message, getPerson());

Since you copy the result in the caller, why not passing the buffer directly: 由于您将结果复制到调用方中,为什么不直接传递缓冲区:

    char message[255];
    someoneDidSomething(message);

then your routine starts with: 然后您的例程开始于:

void someoneDidSomething(char *message)
{
    strcpy(message, getPerson());

you may also consider a single sprintf instead of all those function calls... 您也可以考虑使用一个sprintf而不是所有这些函数调用...

and doesn't return anything (no need). 并且不返回任何内容(不需要)。 Also allows your method to be called safely in a multithreaded environment (well safely if the length of the resulting string doesn't exceed the length of the buffer, eternal problem) 还允许在多线程环境中安全地调用您的方法(如果结果字符串的长度不超过缓冲区的长度,将是安全的,这是永恒的问题)

In addition to the answer by @Jean-François Fabre, you can fix your program by replacing static memory with dynamic memory. 除了@Jean-FrançoisFabre的回答外,您还可以通过将static内存替换为动态内存来修复程序。 Just make sure to free() everything allocated: 只要确保free()分配的所有内容:

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

char* someoneDidSomething (void);

int main ()
{
    for (int i = 0; i <= 10; i++)
    {
        char* message = someoneDidSomething();
        printf ("Because %s\n", message);
        free(message);
    }
}

char* someoneDidSomething (void)
{
    char* message = malloc(256);
    message[0] = '\0'; // strcat expects a null terminated string!

    strcat (message, "Bob");
    strcat (message, " ");
    strcat (message, "jumped");
    strcat (message, " ");
    strcat (message, "high");
    strcat (message, ".");

    return message;
}

you should not declare a static variable. 您不应声明静态变量。 please just try as follow. 请尝试如下。 it would work. 它会工作。

char* someoneDidSomething()
{
char message[255]; //just remove static keyword
strcat (message, getPerson());
strcat (message, " ");
strcat (message, getVerb());
strcat (message, " ");
strcat (message, getSomething());
strcat (message, ".");
return message;
}

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

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