queryPoint=(double*)malloc(sizeof(double**));
queryPoint[qp_count]=(double*)malloc(sizeof(double*)*2);
Вы явно запутались в приведении, размерах и других свойствах malloc
, поэтому давайте начнем с синтаксиса правильного malloc.
Во-первых, в C нет необходимостиприведите результат операции malloc, поскольку он всегда возвращает указатель - тип указателя относится к типу указанных данных, а не к самому указателю, который всегда будет размером регистра.В C ++, однако, это необходимо для его приведения.
Теперь общий синтаксис malloc таков:
TYPE* pointer = malloc(n * sizeof(TYPE));
Где TYPE
- некоторый тип.sizeof
всегда должен быть на один уровень косвенности меньше указателя, на который вы размещаете.(Так что TYPE**
даст вам маллок TYPE*
).n - это количество блоков такого размера, которое нужно выделить, поэтому, если вы хотите выделить 100 дублей, это n
.
В любом случае вы объявили double** queryPoint;
, поэтому ваш первый malloc должен быть:
queryPoint = (double**) malloc(some_size*sizeof(double*));
Это дает нам массив указателей размером some_size
.Как и любой другой массив, вы можете realloc
сделать это так, как вам нужно, хотя предварительное определение суммы, вероятно, идеально.Затем для каждой строки, которую вы хотите выделить, вы просто выбираете смещение из queryPoint
и выделяете массив значений типа double, на которые указывает этот конкретный указатель, например:
queryPoint[i] = (double*) malloc(sizeof_this_array*sizeof(double));
Затем, доступ к определенномуточка в двумерном массиве задается двумя индексами: queryPoint [x] [y];
Как уже говорили другие, realloc
- вариант, но я советую каждый раз, когда вы переполняете массив, вы добавляете фиксированное количествоили просто удвоить то, что у вас есть, так как память (относительно) дешева, и это сэкономит системный вызов или шесть.
Теперь я говорил об указателях и т. д., поэтому я собираюсь нарисовать обязательныйТаблица памяти, чтобы вы могли видеть, как это выглядит:
|Address | Contents | Comments
|-------------|---------------|-------------------------
|0x12345 | 0x20000 | double** queryPointer
| ... | ... | ...
|0x20000 | 0x30000 | double* queryPointer[0]
|0x20001 | 0x30016 | double* queryPointer[1]
|0x20002 | 0x30032 | double* queryPointer[2]
| ... | ... | ...
|0x30000 | 0183737722122 | These together make up the floating
|0x30001 | 0183737722122 | point at double queryPointer[0][0]
|0x30002 | 0183737722122 |
| ... | ... | ...
|0x30016 | 0183737722122 | These together make up the floating
|0x30017 | 0183737722122 | point at double queryPointer[0][1]
|0x30018 | 0183737722122 |
| ... | ... | ...
Указатель - это просто адрес, содержащий адрес, поэтому 0x12345
просто указывает на начало набора адресов с первого malloc.Это массив указателей, то есть просто набор адресов памяти, содержащих адреса памяти, которые указывают на фактические значения, как показано в диапазоне 0x3***
.Обратите внимание, что все размеры адресов, размеры данных и представления значений в значительной степени являются мусором.
Это то, что происходит .
Кроме того, не забудьте free()
для каждого выделенного вами адреса памяти.