【问题标题】:Error while freeing double pointer in C在 C 中释放双指针时出错
【发布时间】:2013-02-27 16:13:04
【问题描述】:

我正在为遗传算法编写代码,但我被困在无法释放未使用内存的地步。这是我的 main() 代码:

    szChromosomes = initial_population(&data[0]);
while (iCurrentGen <= data->m_iMaxGenerations)
{
    arrfSelectedChromosomes = selection(&data[0], szChromosomes);
    iSelectedLen = order_descending_grid(arrfSelectedChromosomes);
    szAuxGen = crossover(&data[0], arrfSelectedChromosomes, szChromosomes);
    free_generation(&data[0], szChromosomes);//Error line
    szChromosomes = szAuxGen;
    szAuxGen = NULL;
}

initial_population(&data[0]) 像这样创建 szChromosomes 数组(我稍后会尝试释放它):

char** initial_population(struct INPUT_DATA* d)
{
int i, j = 0;
float fMember = 0.0;
char** szChromosomes = (char**)malloc(d->m_iPopulationSize * sizeof(char*));

srand(time(NULL));
for (i = 0; i < d->m_iPopulationSize; ++i)
{
    szChromosomes[i] = (char*)malloc(d->m_iBitsPChromosome * sizeof(char));
    for (j = 0; j < d->m_iBitsPChromosome; ++j)
    {
        szChromosomes[i][j] = rand_1_0(0.0, 1.0) == 1? '1' : '0';
    }
    szChromosomes[i][j] = '\0';
}

return szChromosomes;

}

当我调用 free_generation 函数时,下面的 For 循环被执行:

    int i;

for (i = 0; i < d->m_iPopulationSize; ++i)
{
    free(szChromosomes[i]);
}

free(szChromosomes);
szChromosomes = NULL;

当第一次调用free(szChromosomes[i]);发生,我收到以下错误:

检测到堆损坏:在正常块 (#99) 之后。 CRT 检测到应用程序在堆缓冲区结束后写入内存。

【问题讨论】:

  • 试试(char*)malloc(d-&gt;m_iBitsPChromosome + 1);。最后,您需要为'\0' 添加一个额外的字符。乘以 sizeof(char) 是多余的,因为标准定义的 char 大小为 1 个字节。

标签: c memory free genetic-algorithm


【解决方案1】:
char** initial_population(struct INPUT_DATA* d)
{
int i, j = 0;
float fMember = 0.0;
char** szChromosomes = (char**)malloc(d->m_iPopulationSize * sizeof(char*));

srand(time(NULL));
for (i = 0; i < d->m_iPopulationSize; ++i)
{
    szChromosomes[i] = (char*)malloc(d->m_iBitsPChromosome * sizeof(char));
    for (j = 0; j < d->m_iBitsPChromosome; ++j)
    {
        szChromosomes[i][j] = rand_1_0(0.0, 1.0) == 1? '1' : '0';
    }
    szChromosomes[i][j] = '\0';
}

return szChromosomes;

您在每个字符串 szChromosomes[i] 的末尾插入一个 '\0' 但只使用长度为 d->m_iBitsPChromosome 的 malloc

所以你试图在内存中写得太远。要更改它,只需将您的第二个 malloc 更改为:

szChromosomes[i] = (char*)malloc((d->m_iBitsPChromosome + 1) * sizeof(char));

【讨论】:

  • 问题是 \0 字符多了一个字节!我不敢相信我错过了这么多!谢谢你们!
【解决方案2】:
szChromosomes[i][j] = '\0';

此行写入不属于您的内存。

例如。举个例子

char * p;
p = malloc(2);
p[0] = 'a';
p[1] = 'b';

你不应该这样做

p[2] = '\0'

在此之后,因为您只分配了 2 个字节,但您正在写入 3 个字节。

您可以通过两种方式解决此问题

  1. 你需要'\0'吗?除非您打算使用来自&lt;string.h&gt; 的函数之一,它需要一个“\0”来检查结尾,否则您需要用“\0”终止它。在您自己的遍历数组的代码中,您可以使用以 ctr &lt; d-&gt;m_iBitsPChromosome 结束的 for 循环进行遍历。

  2. 或者你可以分配malloc(d-&gt;m_iBitsPChromosome + 1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 2016-05-08
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    • 2014-06-22
    • 2017-08-24
    相关资源
    最近更新 更多