【问题标题】:freeing substring in c - loopc - 循环中释放子字符串
【发布时间】:2010-07-06 15:04:53
【问题描述】:

我正在尝试为结构“structs”的每个成员获取一个子字符串,然后将该子字符串分配给temp_struct 的新成员。 我遇到的问题是如何在每次迭代时释放子字符串,由于某种原因代码运行,但是valgrind 抛出一个Invalid read of size 1,我假设我正在读取内存块。

如何释放子字符串?

谢谢

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

struct st_ex {
    char product[16];
    float price;
};
struct st_temp {
    char *prod;
};

char *temp = NULL;

// from stackoverflow
char* substr( const char* source, size_t start, size_t end )
{
    char* dest = malloc( end - start + 1) ;
    memcpy( dest, &source[start], end - start ) ;
    dest[end - start] = 0 ;
    return dest ;
}

int main()
{
    struct st_ex structs[] = {{"mp3 player", 2.0f}, {"plasma tv", 20.0f},
                              {"notebook", 10.0f},  {"smartphone", 49.9f},
                              {"dvd player", 10.0f}, {"matches", 0.2f }};
    struct st_temp **temp_struct;

    size_t j, i;
    temp_struct = malloc(sizeof *temp_struct * 6);
    for (j = 0; j < 6; j++)
        temp_struct[j] = malloc(sizeof *temp_struct[j]);

    size_t structs_len = sizeof(structs) / sizeof(struct st_ex);

    for(i=0; i<structs_len; i++){
        temp = substr(structs[i].product, 0, 4);
        temp_struct[i]->prod = temp;
        free(temp);
        temp = NULL;
    }
    for(i=0; i<6; i++ )
        printf("%s\n",temp_struct[i]->prod);

    for(i=0; i<6; i++ )
        free(temp_struct[i]);

    free(temp_struct);
    return 0;
}

【问题讨论】:

  • 很棒的信息,谢谢大家!

标签: c struct free malloc substring


【解决方案1】:

1) 你正在释放子字符串

    temp = substr(structs[i].product, 0, 4); 
    temp_struct[i]->prod = temp; 
    free(temp); 

上面的第三行释放了您在substr 中分配的内存。

2) 因为您在此处释放内存,所以引入了一个错误。
释放后无法访问malloc的内存,因此尝试打印temp_struct[i]-&gt;prod是无效的。

解决方案?
不要free(temp),而是在你的循环中释放temp_struct[i],你首先需要释放temp_struct[i]-&gt;prod,像这样

for(i=0; i<6; i++ )     
{
    free(temp_struct[i]->prod);
    free(temp_struct[i]);    
}

【讨论】:

    【解决方案2】:

    Josh,您的 temp_struct 正在保留子字符串...您不想在当前正在释放它的位置释放子字符串。无效读取来自这一行:

    for(i=0; i<6; i++ )
        printf("%s\n",temp_struct[i]->prod);
    

    相反,您希望在释放临时结构时释放子字符串,如下所示:

    for(i=0; i<6; i++ )
    {
        free(temp_struct[i]->prod);
        free(temp_struct[i]);
    }
    

    【讨论】:

      【解决方案3】:

      不要释放子字符串。在 C 中,子字符串是原始字符串的一部分。如果要获取独立于字符串的子字符串,请使用strdup。

      【讨论】:

      • Josh 正在为子字符串分配内存,因此他需要释放它。如果他确实使用了 strdup,他应该在哪里释放被复制的字符串?
      猜你喜欢
      • 2019-09-16
      • 1970-01-01
      • 2017-12-14
      • 2015-11-28
      • 2014-08-05
      • 2016-02-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      相关资源
      最近更新 更多