Я пытаюсь смоделировать поведение векторного контейнера, когда используется push_back. Я создал массив указателей. Каждый элемент может иметь разную длину, поэтому мне нужно перераспределять каждый раз, когда новый элемент сохраняется:
void *reallocf(void *p, size_t s)
{
void *tmp = realloc(p, s);
if(tmp) return tmp;
free(p);
return NULL;
}
int main(){
int rows = 9000;
int cols = 23000;
int *matrix = (int*)malloc(sizeof(int)*rows*cols);
//counter of elements
int *nums = new int [rows];
memset(num, 0, sizeof(int)*rows)
/* populate matrix*/
....
int **Xcc = new int *[rows];for(i = 0; i < rows; i++){
for(k = 0; k < cols; k++){
if(matrix[i*cols +k] == 0){
Xcc[i] = (int*) reallocf(Xcc[i], sizeof(int)*(num[i]+1));
Xcc[i][num[i]] = k;
num[i]++;
}
}
}
}
В основном то, что я делаю, это сохранение позиции элемента, равного 0. Итак, массив Xcc[i]
это увеличение на один элемент каждый раз, когда это необходимо. Новая длина будет предыдущей плюс 1, которая будет сохранена.
Видимо, мне это подходит, но это зависит от того, что я получаю segmentation faults
и после того, как я посмотрел на него с разных сторон, я застрял. Любая помощь будет отличной, идеи или предложения.
Вероятно, проблема заключается в следующем: когда вы делаете
int **Xcc = new int *[rows];
Xcc [i] для универсального i не инициализируется, тогда вызов realloc () может когда-нибудь работать (если Xcc [i] равен нулю), а иногда нет (segfault).
Вам не хватает:
memset(Xcc, 0, sizeof(int*) * rows);
Вам не нужно явно free
перераспределенный указатель realloc
, realloc
освобождает указатель, переданный ему (если его нет NULL
).
Так удали free(p);
от твоего reallocf()
функция.
И, как отметил @ Joachim Pileborg, вы не можете перераспределить память, выделенную new
, Так что меняй new
в malloc
,
if(matrix[i*cols +k] == 0){
Xcc[i] = (int*) reallocf(Xcc[i], sizeof(int)*(num[i]+1));
Xcc[i][num[i]] = k; // bad access here
Во-первых, вы перераспределяете память на основе условия, которое может быть допустимым для нескольких значений k
или же j
,
Во-вторых, когда происходит сбой realloc, вы возвращаете null
и попробуйте получить доступ к памяти 0
при выполнении
Xcc[i][num[i]] = k;
Вопросы
matrix
после matrix[i*cols +k] == 0
правда?замечания
1
когда нет места! Это ужасно неэффективно, потому что после некоторого момента каждая вставка требует одного перераспределения.Вам не нужно reallocf
, При сбое realloc исходная память остается нетронутой.
Если невозможно выделить больше места для новых элементов, остановите метод вставки и верните ошибку.