Что не так с указателем выражения в с? - PullRequest
0 голосов
/ 25 февраля 2011

Я использую функцию с сегментом (показанным ниже), который использовался в qsort для сравнения переменных полей, отсортированных в порядке возрастания или убывания. Я добавил третий порядок (сборка 0, убывание 1 и третий порядок 2), где я сортирую классификации газовых и нефтяных скважин в функции NormalizeResClass, которая возвращает различный int для классификаций.

Я добавил код для (typsort == 2), как показано ниже, но он сортируется правильно только тогда, когда у меня есть резервный класс в качестве единственного типа сортировки. Если я сортирую с помощью вторичной сортировки, как по классу резерва, и хорошо назову это, доза не сортируется.

Исходный код в блоке else использует *((int *) перед xval и yval, и я слаба по указателям. Я знаю, что это приведение к int, но функция NormalizeResClass уже возвращает int, поэтому мне не нужно приведение, и если я использую его, я получаю ошибку сегментации.

static char *Strings = NULL; // Global var

int result= 0; // local var
int ft; // local var

// ft is checked before going to this to be >= 0

if (typsort == 2)
{
    // the code that I have added
    result = strncmp (Strings + NormalizeResClass (xval),
                      Strings + NormalizeResClass (yval), ft);
}
else
{
    // this code was there and the sorting was right
    result = strncmp (Strings + *((int *) xval),
                      Strings + *((int *) yval), ft);
}   

Ниже приведена функция нормализации. Возможно, мне нужно убедиться, что все они имеют уникальный число несколько имеют одинаковые.

int NormalizeResClass (char <em>rc)<br>
{<br>
   /</em><br>
      Given a reserve class string , return a reserve class number.<br>
    */  </p>

<p>register int i;<br>
   register char *p, *q;  </p>

<p>static struct<br>
   {<br>
      int index;<br>
      char <em>str;<br>
   }  RCposs[] =<br>
   {<br>
      {<br>
      1, "PROVED DEVELOPED PRODUCING"},<br>
      {<br>
      2, "PROVED PRODUCING SECONDARY"},<br>
      {<br>
      3, "PROVED PRODUCING TERTIARY"},<br>
      {<br>
      1, "PROVED PRODUCING"},<br>
      {<br>
      4, "PROVED SHUT-IN"},<br>
      {<br>
      5, "PROVED DEVELOPED NON-PRODUCING"},<br>
      {<br>
      5, "PROVED NON-PRODUCING"},<br>
      {<br>
      6, "PROVED DEVELOPED BEHIND-PIPE"},<br>
      {<br>
      6, "PROVED BEHIND-PIPE"},<br>
      {<br>
      8, "PROVED UNDEVELOPED SECONDARY"},<br>
      {<br>
      9, "PROVED UNDEVELOPED TERTIARY"},<br>
      {<br>
      7, "PROVED UNDEVELOPED"},<br>
      {<br>
      1, "PROVED"},<br>
      {<br>
      10, "PROBABLE DEVELOPED PRODUCING"},<br>
      {<br>
      11, "PROBABLE PRODUCING SECONDARY"},<br>
      {<br>
      12, "PROBABLE PRODUCING TERTIARY"},<br>
      {<br>
      13, "PROBABLE SHUT-IN"},<br>
      {<br>
      10, "PROBABLE PRODUCING"},<br>
      {<br>
      14, "PROBABLE DEVELOPED NON-PRODUCING"},<br>
      {<br>
      14, "PROBABLE NON-PRODUCING"},<br>
      {<br>
      15, "PROBABLE DEVELOPED BEHIND-PIPE"},<br>
      {<br>
      15, "PROBABLE BEHIND-PIPE"},<br>
      {<br>
      17, "PROBABLE UNDEVELOPED SECONDARY"},<br>
      {<br>
      18, "PROBABLE UNDEVELOPED TERTIARY"},<br>
      {<br>
      16, "PROBABLE UNDEVELOPED"},<br>
      {<br>
      20, "PROBABLE PRIMARY/SECONDARY"},<br>
      {<br>
      21, "PROBABLE SECONDARY"},<br>
      {<br>
      19, "PROBABLE"},<br>
      {<br>
      22, "POSSIBLE DEVELOPED PRODUCING"},<br>
      {<br>
      23, "POSSIBLE PRODUCING SECONDARY"},<br>
      {<br>
      24, "POSSIBLE PRODUCING TERTIARY"},<br>
      {<br>
      25, "POSSIBLE SHUT-IN"},<br>
      {<br>
      22, "POSSIBLE PRODUCING"},<br>
      {<br>
      26, "POSSIBLE DEVELOPED NON-PRODUCING"},<br>
      {<br>
      26, "POSSIBLE NON-PRODUCING"},<br>
      {<br>
      27, "POSSIBLE DEVELOPED BEHIND-PIPE"},<br>
      {<br>
      27, "POSSIBLE BEHIND-PIPE"},<br>
      {<br>
      29, "POSSIBLE UNDEVELOPED SECONDARY"},<br>
      {<br>
      30, "POSSIBLE UNDEVELOPED TERTIARY"},<br>
      {<br>
      28, "POSSIBLE UNDEVELOPED"},<br>
      {<br>
      22, "POSSIBLE"},<br>
      {<br>
      32, "PROSPECTIVE PRIMARY/SECONDARY"},<br>
      {<br>
      33, "PROSPECTIVE SECONDARY"},<br>
      {<br>
      31, "PROSPECTIVE"},<br>
      {<br>
      34, "ANALOGY"},<br>
      {<br>
      35, "DEPLETE"},<br>
      {<br>
      36, "PROV+PROB+POSS UNDEVELOPED RESERVES"},<br>
      {<br>
      37, "PROV+PROB+POSS DEVELOPED RESERVES"},<br>
      {<br>
      38, "PROV+POSS UNDEVELOPED RESERVES"},<br>
      {<br>
      39, "PROV+POSS DEVELOPED RESERVES"},<br>
      {<br>
      40, "PROB+POSS UNDEVELOPED RESERVES"},<br>
      {<br>
      41, "PROB+POSS DEVELOPED RESERVES"},<br>
      {<br>
      42, "PROV+PROB UNDEVELOPED RESERVES"},<br>
      {<br>
      43, "PROV+PROB DEVELOPED RESERVES"},<br>
      {<br>
      44, "RISKED PROV UNDEVELOPED RESERVES"},<br>
      {<br>
      45, "RISKED PROB UNDEVELOPED RESERVES"},<br>
      {<br>
      46, "RISKED POSS UNDEVELOPED RESERVES"},<br>
      {<br>
      47, "RISKED PROV BEHIND-PIPE RESERVES"},<br>
      {<br>
      48, "RISKED PROB BEHIND-PIPE RESERVES"},<br>
      {<br>
      49, "RISKED POSS BEHIND-PIPE RESERVES"},<br>
      {<br>
      50, "PLANT PRODUCTS SALES"},<br>
      {<br>
      51, "PROBABLE PLANT PRODUCTS SALES"},<br>
      {<br>
      52, "POSSIBLE PLANT PRODUCTS SALES"},<br>
      {<br>
      53, "POTENTIAL PLANT PRODUCTS SALES"},<br>
      {<br>
      54, "PROVED GAS PIPELINE SALES"},<br>
      {<br>
      55, "PROBABLE GAS PIPELINE SALES"},<br>
      {<br>
      56, "POSSIBLE GAS PIPELINE SALES"},<br>
      {<br>
      57, "POTENTIAL GAS PIPELINE SALES"},<br>
      {<br>
      58, "PROVED OIL PIPELINE SALES"},<br>
      {<br>
      59, "PROBABLE OIL PIPELINE SALES"},<br>
      {<br>
      60, "POSSIBLE OIL PIPELINE SALES"},<br>
      {<br>
      61, "POTENTIAL OIL PIPELINE SALES"},<br>
      {<br>
   0, NULL /</em> terminator */ }};  </p>

<code>for (i = 0; (q = RCposs[i].str); i++)    
    {   
         p = rc;  
         while (*p++ == *q++)  
            {  
               if ((*q == '\0'))  
                  return RCposs[i].index;  
            }  
    }  
return (0);  
</code>

}

1 Ответ

2 голосов
/ 25 февраля 2011

Исходя из кода, который вы показали, похоже, что глобальная переменная Strings представляет собой большой блок памяти, который содержит много разных строк (предположительно по одной на запись).

Оригинальный код:

result = strncmp (Strings + *((int *) xval),
                  Strings + *((int *) yval), ft);

сравнивает строку в Strings[xval] со строкой в ​​Strings[yval] с максимальной длиной ft.

Я не знаю, что делает функция NormalizeResClass(x), но если она будет работать аналогично старому коду, ей нужно вернуть int, который представляет местоположение начала строка в блоке памяти Strings. Он должен не возвращать индекс, который выходит за пределы этого блока памяти, в противном случае вызов strncmp начнёт читать, кто знает, где.

Обновление:

Похоже, ваша функция NormalizeResClass возвращает целочисленное ранжирование для строки класса ресурса. В этом случае вы должны , а не использовать strncmp() и Strings[] вообще. Код должен выглядеть примерно так:

if (typsort == 2)
{
    int xRank = NormalizeResClass (xval);
    int yRank = NormalizeResClass (yval);
    if (xRank == yRank) { result = 0; }
    else if (xRank > yRank) { result = 1; }
    else if (xRank < yRank) { result = -1; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...