我已經嘗試了我能想到和找到的所有方法,但是我無法將雙指標陣列復制到另一個相同型別的陣列中。我如何在 C 中做到這一點?我正在嘗試復制double *positions_particles_source[3]到double *positions_particles_destination[3]. 我曾嘗試使用直接賦值復制它,memcpy但我沒有成功。我嘗試過的最后一件事是:
double *positions_particles_source[3];
double *positions_particles_destination[3];
char *initial_structure_file_entries[3];
for (i = 0; i < 3; i ) {
positions_particles_source[i] = (double *) calloc(number_particles_total, sizeof(double));
for (j = 0; j < number_particles_total; j ) {
positions_particles_source[i][j] = strtod(initial_structure_file_entries[i], NULL);
}
positions_particles_destination[i] = (double *) calloc(number_particles_total, sizeof(double));
memcpy(positions_particles_destination[i],
positions_particles_source[i],
number_particles_total * sizeof(double));
}
我實際上并不完全確定在這種情況下最推薦按照我的方式處理矩陣資料。我嘗試使用輸入文本檔案中包含的資料double *positions_particles_source[3]來存盤。我對 C 不是很有經驗,并且對如何在這種語言中操作矩陣資料感到非常困惑。我的印象是該行將輸出分配為地址與變數的內容,我認為這更合適。有人可以讓我知道思考如何通過我的代碼中的那一行處理資料的正確方法是什么嗎?我一直以這種方式處理輸入資料的唯一原因是無法以不同的方式進行處理。number_particles_total3positions_particles_source[i][j] = strtod(initial_structure_file_entries[i], NULL);strtod
uj5u.com熱心網友回復:
您有double 指標陣列,因此簡單地將指標從一個陣列復制到下一個陣列不會復制資料。它將復制指向相同資料的指標,無論您使用直接賦值還是memcpy. 這就是所謂的淺拷貝。你想要的是一個深拷貝。這是一個可能的實作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void printArray(double* array[], size_t rows, size_t cols)
{
for (size_t r=0; r<rows; r )
{
for (size_t c=0; c<cols; c )
{
printf("%.2f, ", array[r][c]);
}
printf("\n");
}
}
int main(void)
{
// declare 2 arrays of double pointers
double *positions_particles_source[3];
double *positions_particles_destination[3];
// arbitrarily using 5
size_t number_particles_total = 5;
// allocate space for these pointers to point to
for (size_t i=0; i<3; i )
{
// allocate the space of 5 doubles for each pointer in each array
positions_particles_source[i] =
calloc(number_particles_total, sizeof(*(positions_particles_source[0])));
// ^^ sizeof(*(positions_particles_source[0])) is the preferred
// method for sizing since you get the type "automatically",
// even if the type changes down the line. Later on I got lazy
// and switched to sizeof(double) because it was less typing
if (positions_particles_source[i] == NULL) exit(-1); // handle error how you want
positions_particles_destination[i] =
calloc(number_particles_total, sizeof(*(positions_particles_destination[0])));
if (positions_particles_destination[i] == NULL) exit(-1);
}
// arbitrarily enter some data in first array
for (size_t i=0; i<3; i )
{
for (size_t j=0; j<number_particles_total; j )
{
positions_particles_source[i][j] = (double)i (double)j 100.13;
}
}
printf("printing source array\n");
printArray(positions_particles_source, 3, number_particles_total);
// deep copy into destination
for (size_t i=0; i<3; i )
{
// could also use an inner loop from [0, num_particles)
// and do direct assignment instead of memcpy
memcpy(positions_particles_destination[i],
positions_particles_source[i],
sizeof(double) * number_particles_total);
}
printf("\nprinting dest array\n");
printArray(positions_particles_destination, 3, number_particles_total);
// clear source array
for (size_t i=0; i<3; i )
{
memset(positions_particles_source[i], 0, sizeof(double) * number_particles_total);
}
// you can see the source array is zeroed out here
printf("\nprinting source array\n");
printArray(positions_particles_source, 3, number_particles_total);
// proves dest array has a deep copy since its data is retained even though
// source has been cleared
printf("\nprinting dest array\n");
printArray(positions_particles_destination, 3, number_particles_total);
// clean up
for (size_t i=0; i<3; i )
{
free(positions_particles_source[i]);
free(positions_particles_destination[i]);
}
return 0;
}
輸出:
printing source array
100.13, 101.13, 102.13, 103.13, 104.13,
101.13, 102.13, 103.13, 104.13, 105.13,
102.13, 103.13, 104.13, 105.13, 106.13,
printing dest array
100.13, 101.13, 102.13, 103.13, 104.13,
101.13, 102.13, 103.13, 104.13, 105.13,
102.13, 103.13, 104.13, 105.13, 106.13,
printing source array
0.00, 0.00, 0.00, 0.00, 0.00,
0.00, 0.00, 0.00, 0.00, 0.00,
0.00, 0.00, 0.00, 0.00, 0.00,
printing dest array
100.13, 101.13, 102.13, 103.13, 104.13,
101.13, 102.13, 103.13, 104.13, 105.13,
102.13, 103.13, 104.13, 105.13, 106.13,
演示
編輯:根據您的評論,我認為您對記憶體布局有些困惑。我將嘗試在下面繪制此圖,盡管有軟體可以繪制比這更漂亮的圖片:
假設你有代碼(縮短你的變數名;))
double* dPtrs[3];
在記憶中,這就是你所擁有的
-----------------------------
| double* | double* | double* |
-----------------------------
dPtrs[0] | dPtrs[1] | dPtrs[2]
就在宣告時,這 3 個雙指標無處指向,取消參考它們是未定義的行為。你必須(使用它們分配空間calloc,malloc等),才可以使用它們。每個指標都可以指向一對多double,所以說你這樣做
dPtrs[0] = malloc(sizeof(double) * 4);
假設malloc不回傳 NULL(您應該始終檢查),然后dPtrs[0]指向double記憶體中某處可以容納 4秒的空間:
-----------------------------
| double* | double* | double* |
-----------------------------
dPtrs[0] | dPtrs[1] | dPtrs[2]
^^
| -------------------------------------------------------
~~~~~> | dPtrs[0][0] | dPtrs[0][1] | dPtrs[0][2] | dPtrs[0][3] |
-------------------------------------------------------
You can do something similar for dPtrs[1] and dPtrs[2]. As I hope you can see, dPtrs[i] is a double* type, and dPtrs[i][j] is a double type (always be sure i and j are in bounds). Something like *dPtrs[i][j] is too many dereferences. A double is not an address, and treating it as such will only lead to problems. This is what your compiler is screaming about if I'm understanding you correctly.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/384368.html
上一篇:指向僅回傳0的結構的指標的元素
