提问者:小点点

数组超出作用域后无法释放


我有一个简单char数组用于从管道中读取。 此数组用于无限while循环

int main() 
{   
    mkfifo("process1_write", 0666); 
    mkfifo("process1_read", 0666); 
    int fd1,fd2;  
    fd1 = open(process1_write, O_RDWR);
    fd2 = open(process1_read, O_RDONLY| O_NONBLOCK);  
    std::string outmsg  = "{process: drv_rtnode_1, message: hi}";
    while (1) 
    { 
        char str1[1050];
        printf("cycle %d\n\t",i++);
        int in = read(fd2, str1, 1024);
        if(in>0)
        {
            printf("message: %s, in: %d\n", str1, in); 
            write(fd1, outmsg.c_str(), outmsg.size());
        }
        else
            printf("No content received\n");
        sleep(1);
    } 
    return 0; 
} 

正如您所看到的,str1在堆栈上被实例化为局部变量,所以我希望它在每个while-cycle之后被释放。

然而,我得到的是以下几点:

循环1:从管道接收数据,因此接受if(IN>0)

message: {"msg type": "status inst", "ProcessName": "process1", "StatusDetail": "dettaglio componente"}{"msg type": "status ses", "ProcessName": "process1", "GroupName": "MOT", "GroupSts": "Online", "ActiveSession": "PRI", "StatusDetail": "dettaglio sessione"}, in: 251

in=251,所以它正确地计算了字符数

循环2:从管道接收的数据较少

这一次我收到了以下消息:{“State”:“Alive”}但打印输出如下:

message: {"state":"alive"}tus inst", "ProcessName": "process1", "StatusDetail": "dettaglio componente"}{"msg type": "status ses", "ProcessName": "process1", "GroupName": "MOT", "GroupSts": "Online", "ActiveSession": "PRI", "StatusDetail": "dettaglio sessione"} , in: 17

in=17,因此字符数再次被正确计算,但我的数组根本没有被清空

无论我收到什么样的数据,这种情况都会发生。

我还尝试更改代码,如下所示:

   char* str1 = new char[1050];
    while (1) 
    { 
        printf("cycle %d\n\t",i++);
        int in = read(fd2, str1, 1024);
        if(in>0)
        {
            printf("message: %s, in: %d\n", str1, in); 
            write(fd1, outmsg.c_str(), outmsg.size());
        }
        else
            printf("No content received\n");
        sleep(1);
        delete[] str1;
        str1 = new char[1050];
    } 

但一切都没有改变。 它的行为完全一样。


共1个答案

匿名用户

以下内容:

while (1) 
{ 
    char str1[1050];

在函数调用堆栈上进行分配,但它是这样的吗:

char str1[1050];
while (1) 
{ 

因此该位置被重用,并且只分配了大约1050个字节。

问题是,对于字符串,需要一个nul终止符:

   int in = read(fd2, str1, 1024);
   if (in > 0)
   {
       str1[in] = '\0';

现在,使用较短数据的覆盖不会显示先前的读取。