Ошибка c2100 недопустимое косвенное обращение

Программа которою мне удалось сделать:

#include <iostream>
#include <ctime>

using namespace std;
//создаем динамический массив
int Ini_len_arr() {
  cout << "Enter element of array :";
  int                //длина массива
  cin >> n; cout << endl;
  if (n < 0) {       //если указали число <0, то выводим сообщение
    cout << "Not correct,try again!";
    Ini_len_arr();
  }
  return n;
}
//отображение массива
void print(int n, int* arr) {
  for (int i = 0; i < n; i++) {      //цикл прохождения по массиву 
    arr[i] = rand() % 30;            //заполнение случайными числами
    cout << arr[i] << " ";           //вывод массива на экран
  }
}
//сортировка пузырьком (понадобится для поиска двоичным методом)
void sort(int n, int* arr) {
  int tmp;                                     //выделения памяти для обмена 
  for (int j = 0; j < n - 1; j++) {            //проход по массиву
    for (int i = 0; i < n - 1; i++) {
      if (arr[i] > arr[i + 1]) {               //сравнение 2х элементов 
        tmp = arr[i];              //если элементы стоят не правильно то меняем их местами
        arr[i] = arr[i + 1];
        arr[i + 1] = tmp;
      }
    }
  }
}
//поиск двоичным методом
void findbin(int n, int* arr, int key) {
  int l = arr[0];      //обозначаем грани отсортированного массива l-мин h-макс значение
  int h = arr[n-1];
  int iter=0;          // переменная для вычисления итераций
  unsigned int start_time1 = clock();    //момент начала отчёта времени поиска
  while (l <= h) {     // цикл прекратится когда число будет найдено
    iter++;            // почёт итераций
    int m = (l + h) /     //поиск центра 
    if (arr[m] == key) {  //когда число будет найдено на кране отобразится индекс элемента
      cout << "Positions:t " << m + 1 << endl << "Iteratoins:t " << iter << endl;
      break;
    }
    if (arr[m] < key) {    //если сокращение массива указало на число меньше чем заданное
      l = m + 1;
    }
    if (arr[m] > key) {   //если сокращение массива указало на число больше чем заданное
      h = m - 1;
    }
  }
  unsigned int end_time1 = clock();  //момент остановки времени
  unsigned int search_time1 = end_time1 - start_time1;  //сколько времени прошло
  cout << "Time:t " << search_time1 << "ms" << endl;   //вывод времени
}
//поиск с барьером
void findbar(int arr[], int n, int key) {
  int iter = 0;
  if (arr[n - 1] != key) {//проверка не является ли заданный элемент не является последним
    arr[n - 1] = key;  //становление на последнее место элемент который ищем  
    int i = 0;
    unsigned int start_time = clock();
    while (arr[i] != key)       //цикл продолжается пока не найдёт число
    {
      i++;       //поиск индекса 
      iter++;    //вычисление кол-во итераций
    }
    cout << "Positions:t " << i + 1 << endl << "Iteratoins:t " << iter << endl;
    unsigned int end_time = clock();
    unsigned int search_time = end_time - start_time;
    cout << "Time:t " << search_time << "ms" << endl;
  }
  else {
    cout << "Positions:t " << n << endl << "Iteratoins:t " << 1 << endl;
    cout << "Time:t " << 1 << "ms" << endl;
  }
}
//тело программы  
void menu(int k, int* arr, int n) {
  int key;             //число которое будем искать
//выбор способа
  if (k == 1) {        //поиск с барьером
    cout << "key ";
    cin >> key;
    findbar(arr, n, key); 
  }
  else if (k == 2) {     // поиск двоичным методом 
    cout << "key ";
    cin >> key;
    sort(n, arr);
    findbin(n, arr, key);
  }
  else {                // если выбор не соответствует вариантам  
    cout << "Not correct, try again: ";
    cin >> k;
    if (k >= 3) {
      menu(k, arr, n); // просим повторить попытку
    }
    else {
      menu(k, arr, n);
    }
  }
}

int main() {
  int k;
//создание массива
  int n = Ini_len_arr();
  int* arr = new int[n];
//отображение массива
  print(n, arr);
  cout << endl;
//визуальное меню
  cout << "Search:" << endl << "1-barier ; 2- binary" << endl << "your choise: ";
  cin >> k;       //выбор варианта поиска 
  menu(k, arr, n);
}

randomer

0 / 0 / 0

Регистрация: 19.02.2014

Сообщений: 9

1

02.10.2014, 16:33. Показов 2199. Ответов 6

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Просьба помочь с пониманием указателей в функциях.
Переползаю с delphi, поэтому просьба сильно не пинать.
Есть большая программа, пытаюсь написать отдельный модуль,
он получает данные из основной программы,
обрабатывает «кусками» и выдаёт обратно результат.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int  c_dec(const void *input, int inputSizeBytes, void *output, 
        int *outputSizeBytes)
{   
    const guint8 *dataIn = (const guint8 *)input; //типизируем входные данные?
    guint16 *dataOut = (guint16 *)output; //типизируем выходные данные?
    short           synth[80];              
....
    for (fr_num=0; fr_num<FramePerInput; fr_num++){
        //работает функция с блоком данных, выводит в synth
        for (j=0; j<80; j++){
            *dataOut[j+(fr_num)*80]=synth[j]; //Передаём "кусок" данных на выход 
        }
    }
    *outputSizeBytes=FramePerInput*(80*(sizeof (short))); // сообщаем количество данных на выходе
....
}

При моём текущем понимании указателей, правильная «конструкция»:

C
1
*dataOut[j+(fr_num)*80]=synth[j];

Но не пропускает nmake: «error C2100: недопустимое косвенное обращение»
Если пишу

C
1
dataOut[j+(fr_num)*80]=synth[j];

компилируется, но программа «падает»
Так-же и с «*outputSizeBytes»…

Добавлено через 7 минут
Забыл добавить: основная программа сменила версию, и в новой уже не работает.
В предыдущей версии работало с разименованными переменными.
Т.е. дело в том как вызывается функция, с какими параметрами?



0



Эксперт Java

4450 / 2683 / 482

Регистрация: 28.04.2012

Сообщений: 8,539

02.10.2014, 17:42

2

Цитата
Сообщение от randomer
Посмотреть сообщение

правильная «конструкция»

Это по каким правилам она правильная?

Добавлено через 1 минуту

Цитата
Сообщение от randomer
Посмотреть сообщение

Если пишу … компилируется, но программа «падает»

А где проверка выхода за границу массива output?



0



0 / 0 / 0

Регистрация: 19.02.2014

Сообщений: 9

02.10.2014, 18:04

 [ТС]

3

Цитата
Сообщение от korvin_
Посмотреть сообщение

Это по каким правилам она правильная?

При моём текущем понимании указателей :-)
Чувствую — неправильное.
Смущает то, что модуль писал по образу и подобию работающего, там именно так работает.

Цитата
Сообщение от korvin_
Посмотреть сообщение

А где проверка выхода за границу массива output?

Не делал, потому что без этого работало в предыдущей версии основной программы…



0



153 / 148 / 66

Регистрация: 20.02.2014

Сообщений: 556

02.10.2014, 19:17

4

randomer, а что передается в output при вызове функции?



0



Модератор

Эксперт PythonЭксперт JavaЭксперт CЭксперт С++

11892 / 7265 / 1720

Регистрация: 25.07.2009

Сообщений: 13,298

02.10.2014, 20:26

5

Цитата
Сообщение от randomer
Посмотреть сообщение

там именно так работает

Значит нужно смотреть, как в предыдущей версии устанавливалась переменная

Цитата
Сообщение от randomer
Посмотреть сообщение

FramePerInput

и как задавался размер строки массива

Цитата
Сообщение от randomer
Посмотреть сообщение

dataOut

и искать отличия.
Кстати, выражение

Цитата
Сообщение от randomer
Посмотреть сообщение

j+(fr_num)*80

в качестве индекса внутри строки двумерного массива выглядит более, чем подозрительно. Такое чувство, что если убрать это +(fr_num)*80 то всё заработает…



0



randomer

0 / 0 / 0

Регистрация: 19.02.2014

Сообщений: 9

03.10.2014, 10:51

 [ТС]

6

Основная программа — wireshark.
Модуль — это декодер голоса из G.729, выдаёт декодированный голос.
Данные на входе — захваченный пакет с данными.
Он дробится на кадры, их количество описывает FramePerInput = inputSizeBytes/10;
Декодируется покадрово, декодированный кадр записывается в dataOut, размер декодированного кадра так-же известен = 80.
Т.е. конструкция

C
1
j+(fr_num)*80

вполне нормальная.
Писал модуль на основе аналогичного для G.711, который идёт в «поставке» с исходниками программы, там работали с данными не разименовывая, например:

C
1
*outputSizeBytes = inputSizeBytes * 2;

что и внесло сумятицу в голову.
Получается при вызове функции передаются данные не таким способом теперь (не в том виде — не адресом в памяти)?
Ибо в предыдущей версии модуль работал…



0



0 / 0 / 0

Регистрация: 19.02.2014

Сообщений: 9

08.10.2014, 11:16

 [ТС]

7

Доброго всем времени суток.
Заработало: действительно надо было смотреть как вызывается функция…
Функция декодирования вызывается 2 раза, первый раз она должна вернуть исключительно будущий размер декодированных данных.
Чтобы при повторном вызове дали место нужного размера под запись этих данных.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

08.10.2014, 11:16

Помогаю со студенческими работами здесь

Вывести указатель — куча ошибок (недопустимое косвенное обращение, …)
Простите, туплю жестоко. Два месяца не трогал студию, забыл все конкретно.

int peremennaya=5461;…

Ошибка «Access denied» error 5 при вызове VirtualQueryEx
Всем привет. Не могу понять в чём проблема, запускаю программу от имени администратора, но данные…

«Недопустимое использование этого типа в качестве выражения»
Вот, у меня есть код (просто создаёт пустое окно без ничего), который без проблем собирается и…

Недопустимое использование оператора «PRINT», оказывающего побочное действие, в функции
Функция должна считать факториал, но выводит ошибку:
Сообщение 443, уровень 16, состояние 14,…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

7

I have a C application that I’ve created in VS2008. I am creating a mock creation function that overrides function references in a struct. However if I try and do this in a straight forward fashion with something like:

void *ptr = &(*env)->GetVersion;
*ptr = <address of new function>

then I get a «error C2100: illegal indirection» error as *ptr, when ptr is a void * seems to be a banned construct. I can get around it by using a int/long pointer as well, mapping that to the same address and modifying the contents of the long pointer:

*structOffsetPointer = &(*env)->GetVersion;
functionPointer = thisGetVersion;
structOffsetPointerAsLong = (long *)structOffsetPointer;
*structOffsetPointerAsLong = (long)functionPointer;

but I am concerned that using long or int pointers will cause problems if I switch between 32 and 64 bit environments.

So is there are easy way to disable this error? Assuming not, is either int or long 64 bits under win64?

asked Oct 14, 2008 at 22:13

David Arno's user avatar

David ArnoDavid Arno

42.6k16 gold badges85 silver badges131 bronze badges

Then how about:

void **ptr = (void **) &(*env)->GetVersion;
*ptr = <address of new function>

The right way to do this is to work with the type system, avoid all the casting and declare actual pointers to functions like:

typedef int (*fncPtr)(void);
fncPtr *ptr = &(*env)->GetVersion;
*ptr = NewFunction;

The above assumes GetVersion is of type fncPtr and NewFunction is declared as
int NewFunction(void);

answered Oct 14, 2008 at 22:33

Tony Lee's user avatar

1

When dereferencing a «void *», you are left with a «void» which is has no size (or really no type for that matter), so it doesn’t know how to assign something to it. It is the same as:

void blah = 0xdeadbabe; // let's assume a 32-bit addressing system

To add to my own response and give a solution, I would give it the proper type of a pointer to a function of the type GetVersion is. If GetVersion that your «env» struct field is pointing to is:

int GetVersion();

then you want:

int (**ptr)() = &(*env)->GetVersion;

answered Oct 14, 2008 at 22:25

Jim Buck's user avatar

Jim BuckJim Buck

20.4k11 gold badges55 silver badges74 bronze badges

3

Last time I played with void* & C under visual studio, VS didn’t play nicely.
Here are some information datapoints:

A pointer is always the size of the system word(8/16/32/64)…(unless you have segmented memory, which I’m assuming you don’t have). This is because it needs to point to anywhere in the memory space. For a von Neumann machine, a function pointer is going to be the same size as a data pointer, because data and code occupy the same memory space. This is not guaranteed under a Harvard architecture. I’m not familiar enough with Windows Vista to know if it programatically fakes out a Harvard architecture for security reasons.

I personally would not disable this error, just for the sake of letting the compiler do its job.

answered Oct 14, 2008 at 22:21

Paul Nathan's user avatar

Paul NathanPaul Nathan

39.4k28 gold badges112 silver badges211 bronze badges

As mentioned, to store the address of a function in a pointer you should simply not do the indirection.

However, you also talk about being worried about the size of an int type that you might store a pointer into (which generally is not something you want to do unless you have a really good reason to).

If you want to hold a pointer in an int type for some reason, then on Windows a UINT_PTR type (or uintptr_t from stdint.h if you have it) will hold most pointer types (I don’t think it’s necessarily large enough to hold some pointer-to-member types).

answered Oct 14, 2008 at 22:22

Michael Burr's user avatar

Michael BurrMichael Burr

332k50 gold badges530 silver badges756 bronze badges

2

Я не понимаю эту ошибку (C2100: незаконное косвенное обращение). Я отметил три экземпляра — все они находятся внизу. Я искал в Интернете и знаю, что это связано с моими указателями, но после 8 часов на это я полностью потерялся. Здесь могут быть и другие ошибки, но я даже не могу сказать, потому что не могу его скомпилировать. Пожалуйста, помогите, и мне бы хотелось получить объяснение, которое я могу понять, чтобы я мог понять, что я делаю не так, в будущем.

// INCLUDE FILES
#include <stdio.h>
#include <string.h>

// PROGRAM CONSTANTS
#define     MAX_MSG_LEN     81      // Maximum Message Length (Including /0 Character)

// FUNCTION PROTOTYPES
void printLength(int, int);         // Function to Validate & Print Length of String
void printString(int, char);        // Function to Print the String in Reverse
void writeToFile(int, char);

// GLOBAL VARIABLES
char input[MAX_MSG_LEN];            // Input String
int maxLength = MAX_MSG_LEN - 1;    // Actual String Length (Not Including /0 Character)
char *ptr = input;                  // Character Pointer to String
int length = 0;                     // Length of Current String
int lcv = 0;                        // Loop Control Variable


void main()
{
    FILE *ifp;
    ifp = fopen("reverseString.txt", "w");

    printf("nnEnter a String Between 1 and %d Characters: ", maxLength);  // Prompts User to Enter a String Less Than 80
    gets(input);        // Receives the Inputted String from the User   

    length = strlen(input);     // Counts the Length of the Inputted String & Assigns the Number to the "length" Variable

    printLength(length, maxLength);
    printString(length, *ptr);
    writeToFile(length, *ptr);
}

void printLength(int length, int maxLength)
{
    if(length > maxLength)
    {
        printf("nnThe Maximum Length of %d Characters was Exceeded!", maxLength);
        printf("nProgram Terminated...nn");
        exit(0);
    }

    printf("nnThe Length of the Input String was: %dn", length);     // Prints the Length of the Inputted String
}

void printString(int length, char ptr)
{   
    for(; lcv < length; lcv++)
    {
        ptr++;
    }

    length = lcv;
    printf("nThe String in Reverse: ");

    for(ptr--; length > 0; length--)
    {
        printf("%c", *ptr);     // HERE IS ONE INSTANCE OF C2100
        *ptr--;                 // HERE IS ONE INSTANCE OF C2100
    }

    printf("nn");
    return;
}

void writeToFile(int length, char ptr)
{
    FILE *ifp;
    ifp = fopen("reverseString.txt", "w");
    fprintf(ifp, "%c", *ptr);   // HERE IS ONE INSTANCE OF C2100
    fclose(ifp);
}

2 ответа

Лучший ответ

В вашем коде неправильный синтаксис. Вам необходимо изменить декларацию и определение (я)

  void printString(int, char);

К

  void printString(int, char*);

И назовите это как

 printString(length, ptr);

То же самое и с функцией writeToFile().

В противном случае, с текущим кодом, в функциях printString() и writeToFile(), с определением, подобным char ptr, ptr не является типом указателя, который можно разыменовать.

Это сказало,

  • Никогда не используйте gets(), у него проблемы с переполнением буфера, используйте fgets() вместо этого.

  • Всегда проверяйте возвращаемое значение из fopen() перед использованием возвращаемого указателя, чтобы гарантировать успешность вызова.

  • Чтобы соответствовать стандартам, void main() должно быть как минимум int main(void).


3

Sourav Ghosh
25 Янв 2016 в 07:49

2) включить заголовок {{X0}} для поддержки функции {{X1}}, поскольку определение {{X2}} доступно в {{X3}}…

1) Попробуйте изменить объявления функций printString() и writeToFile(), как предложил Саурав Гош.

2) включить заголовок stdlib.h для поддержки функции exit(), поскольку определение exit() доступно в stdlib.h

3) Измените void main(){/* your code*/} на int main(){/* your code */}

Я внес указанные выше изменения, и он успешно скомпилирован на моей машине.


2

SKD
25 Янв 2016 в 08:55

Пожалуйста, посмотрите на следующий код

double RTMotionDetector::getMSE(Mat I1, Mat I2)
{
Mat *s1;
cv::absdiff(*I1, *I2, *s1);       // |I1 - I2|
*s1->convertTo(*s1, CV_32F);  // cannot make a square on 8 bits
*s1 = s1->mul(*s1);           // |I1 - I2|^2

Scalar s = sum(*s1);         // sum elements per channel

double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels

if( sse <= 1e-10) // for small values return zero
return 0;
else
{
double  mse =sse /(double)(I1.channels() * I1.total());
return mse;
// Instead of returning MSE, the tutorial code returned PSNR (below).
//double psnr = 10.0*log10((255*255)/mse);
//return psnr;
}
}

Вот как это называется

getMSE(*currentGrey,*next)

Вот как currentGrey а также next Матовые объекты инициализируются

Mat *current, *currentGrey

Когда я запускаю вышеупомянутый метод, я получаю ошибку error C2100: illegal indirection,

Ошибка исходит из этих двух строк

cv::absdiff(*I1, *I2, *s1);       // |I1 - I2|
*s1->convertTo(*s1, CV_32F);  // cannot make a square on 8 bits

Я сделал все возможное, чтобы решить эту проблему, но не удалось. В любом случае, я довольно новичок в программировании Windows. Пожалуйста помоги.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Ошибка c2082 переопределение формального параметра
  • Ошибка c2065 cout необъявленный идентификатор
  • Ошибка c2061 синтаксическая ошибка идентификатор
  • Ошибка c2059 синтаксическая ошибка константа

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии