#c #pointers #segmentation-fault #printf
#c #указатели #ошибка сегментации #printf
Вопрос:
printf("nframe is: %p",amp;frame);
printf("nframeprev is: %p",amp;framePrev);
какая бы строка ни была первой, она всегда будет правильно напечатана.
Вторая строка всегда будет иметь ошибку сегментации в приведенном выше коде, независимо от того, какой указатель она выводит. есть идеи, почему это происходит? Я пробовал fflush ( стандартный вывод); после каждого printf, но это, похоже, не имеет никакого значения.
указатель удаляется с помощью следующего
frame =(double**) malloc(cols*sizeof(double));
framePrev =(double**) malloc(cols*sizeof(double));
if(frame==NULL||framePrev==NULL){
printf("malloc epic failn");
return 0;
}
/*allocate mem for 2nd dimention*/
for(i=0;i<cols;i ){
frame[i]=(double*) malloc(rows*sizeof(double));
framePrev[i]=(double*) malloc(rows*sizeof(double));
/*check for null pointer*/
if(frame[i]==NULL||framePrev[i]==NULL){
printf("malloc epic failn");
return 0;
}
}
Комментарии:
1. Попробуйте отладчик, подобный
gdb
или инструмент отладки памяти, подобныйvalgrind
. Вероятно, они очень быстро покажут, где именно вы нарушаете сегментацию.2. Вы хотите сказать, что функции printf() следуют за основным кодом?
3. Файлы printf находятся в верхней части цикла for, который выполняется после mallocs, но при первом выполнении цикла он сообщает о сбое сегмента между двумя файлами printf — так что, возможно, это просто сбой сегмента после и printf медленный, я не слишком уверен
4.
frame N is: 0xbffff368 Program received signal SIGSEGV, Segmentation fault.
это результат, который я получаю, и я обычно ожидаю, что второй оператор будет напечатан ниже
Ответ №1:
Я не знаю, почему тот код, который вы предоставили, приведет к segfault. Однако то, что вы пытаетесь распечатать, — это адрес указателя, а не содержимое указателя. Другими словами, frame — это переменная-указатель; она имеет размер 4 байта и находится где-то в стеке / куче. Вы распечатываете адрес этого где-то. Я думаю, вы хотите напечатать значение frame; которое было бы фактическим указателем, содержащимся в этом фрейме. Итак, уберите amp; в каждой строке и посмотрите, что вы получите.
Кроме того, у вас странное распределение памяти. A (double **) — это указатель на массив, который содержит указатели на удвоения; но ваш вызов malloc выделяет массив, который содержит удвоения. Вероятно, вам нужен malloc(cols * sizeof(double *)). Этот код работает, потому что double больше, чем double *, поэтому вы фактически выделяете достаточно памяти, но это все равно неправильно.
Комментарии:
1. Да, это ошибка, должно быть double * при распределении для перехода от указателя к указателю. Неудивительно, что это приводит к сбою.
Ответ №2:
В ваших инструкциях printf нет ничего неправильного. Если вы нарушаете сегментацию, это, вероятно, потому, что у вас ошибка в ваших подпрограммах и у вас разбита память.
Одна из очевидных проблем в том, что вы опубликовали, заключается в том, что ваши массивы frame и frameprev являются не массивами double, а двойными указателями, и маловероятно, что они имеют одинаковый размер. Первые две строки должны быть:
frame =(double**) malloc(cols*sizeof(double *));
framePrev =(double**) malloc(cols*sizeof(double *));
Комментарии:
1. Значение float обычно помещается в регистр, например, является длиной собственного int, например, размером указателя. Удвоение действительно длиннее.
Ответ №3:
просто поместите код в test.cpp файл, подобный этому:
int main(){
int i, cols=4, rows=2;
double **frame =(double**) malloc(cols*sizeof(double));
double **framePrev =(double**) malloc(cols*sizeof(double));
if(frame==NULL||framePrev==NULL){
printf("malloc epic failn");
return 0;
}
/*allocate mem for 2nd dimention*/
for(i=0;i<cols;i ){
frame[i]=(double*) malloc(rows*sizeof(double));
framePrev[i]=(double*) malloc(rows*sizeof(double));
/*check for null pointer*/
if(frame[i]==NULL||framePrev[i]==NULL){
printf("malloc epic failn");
return 0;
}
}
printf("nframe is: %p",amp;frame);
printf("nframeprev is: %p",amp;framePrev);
}
скомпилирован с помощью g test.cpp , запустите его через ./a.out ->
frame is: 0x7fff5fbffaf8
frameprev is: 0x7fff5fbffaf0
нарушения сегментации вообще нет.
как вам скомпилировать? какие-либо другие изменения в вашем коде теперь показаны в вашем сообщении? как вы инициализируете свои переменные?
правила.
Комментарии:
1. спасибо за помощь, ребята, это действительно помогло, вы, ребята, были правы, этот код был в порядке, это была следующая строка, вызывающая проблемы, она просто помешала окончательной печати попасть на терминал (doh! — моя ошибка).