2011-02-02 2 views
3

Я пишу в C для OSX, работая на 64-битной машине в 32-битном режиме. Я собираюсь использовать GCC для 386. Проект большой; Я не видел какого-либо странного поведения от компилятора (возможно, до сих пор.) Приложение многопоточно, и этот код должен быть, но в настоящее время выполняется однопоточным. Я компилирую с помощью независимого положения clib и используя posix-потоки при поточной передаче. Этот код, кстати, действует точно так же, если я do его нить.Мои неподписанные короткие указатели возвращают неожиданные результаты. Зачем?

Следующая упрощенная процедура, демонстрирующая проблему в простейшей форме. В принципе, я перемещаю 16-битные каналы изображения здесь из одного набора из трех каналов RGB (mr, mg, mb) в другой набор из 3 каналов RGB (lr, lg, lb) точно такого же размера. Фрагмент, как я собираюсь сбросить его, работает отлично:

void lrip_me( unsigned short *mr, // RIP from source image 
       unsigned short *mg, 
       unsigned short *mb, 
       unsigned short *lr, // into RGB layer 
       unsigned short *lg, 
       unsigned short *lb, 
       struct layer *lay, 
       long start,long finish) 
{ 
long xw,yw; 
long xf,yf; 
long x,y; 
unsigned long offset; 

    xw = lay->parent->x; 
    yw = lay->parent->y; 
    xf = xw - 1; 
    yf = yw - 1; 

    for (y=start; y<finish; y++) 
    { 
     for (x=0; x<xw; x++) 
     { 
      offset = (y * xw) + x; 
      if (x==0 || x==xf || y==0 || y==yf) // then on edge 
      { 
       lr[offset] = mr[offset]; 
       lg[offset] = mg[offset]; 
       lb[offset] = mb[offset]; 
      } 
      else 
      { 
       lr[offset] = mr[offset]; 
       lg[offset] = mg[offset]; 
       lb[offset] = mb[offset]; 
      } 
     } 
    } 
} 

Как вы можете видеть, действие на краю изображения, так и внутри краев одно и то же; Я просто перемещаю данные. И это работает - вывод этого изображения в каналах lr, lg и lb.

НО. Если в предложении еще, я изменить строки читать ...

  lr[offset] = mr[offset-xw]; 
      lg[offset] = mg[offset-xw]; 
      lb[offset] = mb[offset-xw]; 

... Вы ожидали бы интерьер изображения, чтобы переместить одну строку развертки, так как извлекает данные будут Выходец из полное расстояние от линии сканирования, но переход в неперемещенное целевое местоположение. Вместо этого вывод выглядит совершенно случайным. Словно шорты были загружены на неправильные границы, возможно, или из другого места. Это делает то же самое ...

  lr[offset] = mr[offset-1]; 
      lg[offset] = mg[offset-1]; 
      lb[offset] = mb[offset-1]; 

... там, я ожидаю, что изображение будет перемещаться по одному пикселю по горизонтали. Нет. Тот же результат - чистый хеш.

Я попытался перейти на математику указателя вместо массивов // * (mr + offset-1) // и получить точно такой же результат. Я скомпилировал его в библиотеке и в среде objc. Я попытался использовать даже смещение, думая, возможно, компилятор смущен размером данных. Я получаю одинаковые результаты каждый раз. Значение смещения может использоваться как есть, но ТОЛЬКО как есть. Он не может быть изменен в скобках, и, кроме того, он не может быть изменен вне кронштейнов, просто считаться длинным.

У меня нет идеи, что здесь происходит. Я был бы очень благодарен, если бы кто-нибудь помог мне понять, что есть.

Немного фона; это операция RIP (удаление изолированного пикселя), или, по крайней мере, это будет, если я смогу получить в 8 пикселах, окружающих тот, который в данный момент просматривает цикл. Вот почему кромки обрабатываются по-разному; Я не хочу, чтобы запустить 8-пиксельный lookaround по краям, только внутри них, где я всегда буду иметь все 8 посмотреть на:

ooo 
oxo 
ooo 

В этом тесте, я удалил все RIP кода, поскольку он добавляет много сложности и не проливает свет на проблему. Просто (ха-ха!) Ситутация, где смещения массива и указателя, похоже, не работают разумно.

ответ

1

Ваша функция индекса предполагает, что 2D-массивы находятся в row-major order.

offset = (y * xw) + x; 

Возможно, они находятся в главном приказе.

+0

Макет массивов в памяти полностью определен языком C. Для вариантов исполнения нет места. –

+0

Нет, я тот, кто поставил их в строгом порядке. И, как я уже сказал, пример работает так, как это было дано - выход прекрасен при вычислении; это не так, если расчет смещения был неправильным. Согласовано? – fyngyrz

+0

@fyngyrz, не согласовано. В простом случае копирования (или где-нибудь, где вы работаете только на одном пикселе (элемент массива)), не имеет значения, какой порядок вы выполняете по ним, пока вы все равно генерируете каждое смещение. Однако, думая об этом больше, я думаю, что если бы была проблема с строкой-строкой против большого столбца, тогда ваша вторая модификация ('foo [offset-1]') должна была работать. – rlibby

Смежные вопросы