【问题标题】:C Dynamic allocation of matrices and vectorsC 矩阵和向量的动态分配
【发布时间】:2013-01-11 05:19:57
【问题描述】:

我正在用 C 语言编写这段代码来实现遗传算法。这是我对所有工作结构(矩阵和向量)进行动态分配的部分。当我运行它时,有时(5 次 3 次)它会崩溃。分配有问题?

int main()
{

const char progress[] = "|/-\\";
int n, popSize, numIter,optRoute,minDist,range,globalMin,idx;
int maxcell;
int i,j,p,t,k,d,iter,perm,index,m;
int dists[4];
int* dmat, * totalDist, * distHistory, *randomOrder, *bestOf4Route;
int** pop, ** newPop, ** tmpPop, **rtes;
unsigned int iseed = (unsigned int)time(NULL);

// Values initialization
n = 5;
range = 10;
popSize = 100;
numIter = 1*10^4;
globalMin = 100000;

srand (iseed);

//printf("Insert the number of cities: ");
//scanf("%i",&n);

printf("Matrix costs creation...");
// Creates dmat NxN matrix
// dmat è una matrice triangolare superiore con diag = 0
// declare halfsize 1D array
maxcell = ((n*n)-n)/2;
dmat = (int*)malloc(maxcell * sizeof(int));

//set array
for(i=0; i<maxcell; i++)
    dmat[i] = (rand()%10)+2;

printf("done.\n");

//print entire matrix
//print_triangmat(dmat,n);

printf("Creation of the pop matrix...");
// create popSize x N matrix
pop = (int**)malloc(n * sizeof(int*));
for (i = 0; i < n; i++) {
  pop[i] = (int*)malloc(popSize * sizeof(int));
}

printf("done.\n");
printf("Pop matrix loading...");
// charge the first row of the matrix
for (j = 0; j < n; j++) {
  pop[j][0] = j+1;
}

// charge the rest of the matrix with randperm of the first row
for (i = 0; i < popSize; i++)
{
    for (j = 0; j < n; j++)
    {
        perm = rand()%(n-j)+j;
        t = pop[perm][i];
        pop[perm][i] = pop[j][i];
        if(i!=popSize-1)
        pop[perm][i+1] = pop[j][i];
        pop[j][i] = t;
        if(i!=popSize-1);
        pop[j][i+1] = t;
    }
}
print_matrix(pop,popSize,n);

printf("done.\n");
printf("Creation of the working structures...");

// create 4 x N matrix
rtes = (int**)malloc(n * sizeof(int*));
for (i = 0; i < n; i++) {
  rtes[i] = (int*)malloc(4 * sizeof(int));
}

// Creates an array of popSize
totalDist = (int*)malloc(popSize * sizeof(int));

// Creates an array of numIter
distHistory = (int*)malloc(numIter * sizeof(int));

// Creates an array of n
bestOf4Route = (int*)malloc(n * sizeof(int));

// create 4 x N matrix
tmpPop = (int**)malloc(n * sizeof(int*));
for (i = 0; i < n; i++) {
  tmpPop[i] = (int*)malloc(4 * sizeof(int));
}

// create popSize x N matrix
newPop = (int**)malloc(n * sizeof(int*));
for (i = 0; i < n; i++) {
  newPop[i] = (int*)malloc(popSize * sizeof(int));
}

// Creates an array of popSize
randomOrder = (int*)malloc(popSize * sizeof(int));

printf("done.\n");

【问题讨论】:

  • 应该是 "int main(int argc, char* argv[]) { /*...*/ return 0; }"
  • @IanMallett, main 不必有参数,但它应该返回一个值 c-faq.com/ansi/maindecl.html
  • 我可以上下发誓确实如此,但我承认随后对 C99 和 C++ 标准的检查证明了这一点。谢谢你纠正我。在 C90 中是否也是如此?--我无法获得指向该标准副本的指针。
  • @SamuelEdwinWard int main() 是有效的,但会调用实现定义的行为,而不是 int main(void) 和 int main(int argc char* argv []) More info here。另外,main 不需要返回值,more info here
  • @IanMallett 他实际上比你更困惑。请参阅我上面评论中的上述两个链接。

标签: c vector matrix dynamic-allocation


【解决方案1】:

问题就在这里。考虑 i=popsize-1 然后您将写入 pop[perm][popsize] 这是一个无效的内存位置。然后,当请求以下分配时,有时请求的内存位置与 pop[perm][popsize] 相交,因此您会遇到运行时错误。

for (i = 0; i < popSize; i++) {
    for (j = 0; j < n; j++) {
        perm = rand()%(n-j)+j;
        t = pop[perm][i];
        pop[perm][i] = pop[j][i];
        if(i!=popsize-1)
        pop[perm][i+1] = pop[j][i];
        pop[j][i] = t;
        if(i!=popsize-1)
        pop[j][i+1] = t;
    }
}

另一方面,有很多错误的内存分配:

    pop = (int**)malloc(n * sizeof(int*));
    for (i = 0; i < popSize; i++) {
      pop[i] = (int*)malloc(popSize * sizeof(int));
    }

应该是

pop = (int**)malloc(n * sizeof(int*));
for (i = 0; i < n; i++) {
  pop[i] = (int*)malloc(popSize * sizeof(int));
}

 rtes = (int**)malloc(n * sizeof(int*));
    for (i = 0; i < 4; i++) {
      rtes[i] = (int*)malloc(4 * sizeof(int));
    }

应该是

rtes = (int**)malloc(n * sizeof(int*));
for (i = 0; i < n; i++) {
  rtes[i] = (int*)malloc(4 * sizeof(int));
}

tmpPop = (int**)malloc(n * sizeof(int*));
for (i = 0; i < 4; i++) {
  tmpPop[i] = (int*)malloc(4 * sizeof(int));
}

应该是

tmpPop = (int**)malloc(n * sizeof(int*));
for (i = 0; i < n; i++) {
  tmpPop[i] = (int*)malloc(4 * sizeof(int));
}

这个问题还有一个歧义。

numIter = 1*10^4;

这使得 numIter 为 14,因为 ^ 是逻辑 XOR 运算符。您确定要这样做吗?

【讨论】:

  • pop 和 newpop 应该一样吗?
  • 如果你想要popsizen矩阵你应该先做int* newpop=malloc(popsizesizeof(int),然后分配n*sizeof( int) 对于每个 newpop[i]
  • 当然,其实当我意识到的时候,我用矩阵[M][N]表示了一个NxM矩阵。这有效......但这仍然不是我的问题。问题是有时(不是每次但经常)它会冻结。
  • 好的,我把整个代码都放好了。它冻结在我为所有结构进行分配的地方
  • 我编辑了我的答案,问题出在 for 循环中。此外,不要忘记按照我写的那样更改数组分配。
【解决方案2】:
pop = (int**)malloc(n * sizeof(int*));
for (i = 0; i < popSize; i++) {
  pop[i] = (int*)malloc(popSize * sizeof(int));
}

如果 popSize > n 你有麻烦了...

【讨论】:

    猜你喜欢
    • 2023-03-03
    • 2022-11-02
    • 1970-01-01
    • 2021-10-13
    • 2016-09-12
    • 2011-12-15
    • 2018-04-24
    • 2014-03-25
    • 1970-01-01
    相关资源
    最近更新 更多