Невозможно сохранить значения в матрице, используя c - PullRequest
0 голосов
/ 03 октября 2018

Вот мой код:

typedef struct{

double (*a)[2];
} my_struct;


void update(my_struct* struct1){

struct1 -> a = malloc ( 2*sizeof(struct1->a) );

struct1 -> a[0][0] = 5.0;
struct1 -> a[0][1] = 10.0;
struct1 -> a[1][0] = 3.0;
struct1 -> a[1][1] = 4.0;

printf("%f %f %f\n", struct1->a[0][0], struct1->a[0][1], struct1->a[1][1]);

}


int main(){

my_struct struct1;

update(&struct1);

printf("%f %f %f\n", struct1.a[0][0], struct1.a[0][1], struct1.a[1][1]);


return 0;
}

Итак, в основном я хочу иметь структуру с матрицей (я действительно хочу использовать это определение матрицы с [r] [c] и, таким образом,как я делаю распределение).

Как видите, у меня есть два printfs, чтобы увидеть, что происходит.

В командной строке выводится следующее:

5.000000 10.000000 3.000000
5.000000 10.000000 0.000000

Так почему одно из значений, напечатанных в main (), равно нулю ???

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

После добавления необходимых включений <stdio.h> и <stdlib.h> мы можем запустить код под Valgrind, чтобы увидеть, что не так:

valgrind -q --leak-check=full ./52626203   
==1409== Invalid write of size 8
==1409==    at 0x10919F: update (52626203.c:16)
==1409==    by 0x109209: main (52626203.c:28)
==1409==  Address 0x4a39050 is 0 bytes after a block of size 16 alloc'd
==1409==    at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409==    by 0x10915A: update (52626203.c:12)
==1409==    by 0x109209: main (52626203.c:28)
==1409== 
==1409== Invalid write of size 8
==1409==    at 0x1091B6: update (52626203.c:17)
==1409==    by 0x109209: main (52626203.c:28)
==1409==  Address 0x4a39058 is 8 bytes after a block of size 16 alloc'd
==1409==    at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409==    by 0x10915A: update (52626203.c:12)
==1409==    by 0x109209: main (52626203.c:28)
==1409== 
==1409== Invalid read of size 8
==1409==    at 0x1091C6: update (52626203.c:19)
==1409==    by 0x109209: main (52626203.c:28)
==1409==  Address 0x4a39058 is 8 bytes after a block of size 16 alloc'd
==1409==    at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409==    by 0x10915A: update (52626203.c:12)
==1409==    by 0x109209: main (52626203.c:28)
==1409== 
5.000000 10.000000 4.000000
==1409== Invalid read of size 8
==1409==    at 0x109212: main (52626203.c:30)
==1409==  Address 0x4a39058 is 8 bytes after a block of size 16 alloc'd
==1409==    at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409==    by 0x10915A: update (52626203.c:12)
==1409==    by 0x109209: main (52626203.c:28)
==1409== 
5.000000 10.000000 4.000000
==1409== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1409==    at 0x48357BF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1409==    by 0x10915A: update (52626203.c:12)
==1409==    by 0x109209: main (52626203.c:28)
==1409== 

Это показывает нам, что это попытка присвоить struct1->a[1][0] это ошибка, предполагая, что мы выделили только достаточно места для a[0], а не a[1].

Это приводит нас прямо к строке выделения, где мы видим, что пропустили разыменование в аргументе sizeof.Это должно быть

struct1->a = malloc(2 * sizeof *struct1->a);
//                             ^

Мы выделяли место для двух указателей на двойной массив, а не достаточно для двух двойных массивов по два элемента в каждом.

Кстати, в реальном коде нетне забудьте проверить указатель, возвращенный из malloc(), прежде чем пытаться его использовать, и free(), когда закончите.

0 голосов
/ 03 октября 2018

Я вижу две проблемы.

1) Неверный malloc размер

struct1->a - это указатель, поэтому sizeof(struct1->a) - это размер указателя.То, что вы хотите, это размер первого элемента.Поэтому используйте sizeof(struct1->a[0]) (или sizeof(*struct1->a))

2) Индекс вне диапазона

Ваш код (после исправления размера malloc) создает матрицу 2x2.Таким образом, этот доступ struct1 -> a[1][2] находится вне диапазона

...