void pushSynonyms (string synline, char matrizSinonimos [1024][1024]){
stringstream synstream(synline);
vector<int> synsAux;
int num;
while (synstream >> num) {synsAux.push_back(num);}
int index=0;
while (index<(synsAux.size()-1)){
int primerSinonimo=synsAux[index];
int segundoSinonimo=synsAux[++index];
matrizSinonimos[primerSinonimo][segundoSinonimo]='S';
matrizSinonimos [segundoSinonimo][primerSinonimo]='S';
}
}
и звонок ..
char matrizSinonimos[1024][1024];
pushSynonyms("1 7", matrizSinonimos)
Мне важно передать matrizSinonimos по ссылке.
Обновлено: убрал & из &matrizSinonimos.
Обновлено: ошибка времени выполнения:
An unhandled win32 exception occurred in program.exe [2488]![alt text][1]
Необработанная исключительная ситуация win32 в program.exe [2488]
Вы знаете, где именно он вылетает? Индексы в диапазоне?
Он вылетает при вызове функции, при извлечении matrizSinonimos он снова работает нормально.
Что такое полная ошибка времени выполнения? Включите материал в замещающий текст, что бы это ни было.
какое сообщение об ошибке после того, как вы убрали "&" при передаче?
Вы запускали это в отладчике? Если да, то на какой строке он находится при сбое и каковы значения index, primerSinonimo и segondoSinonimo? (И если вы не запускали отладчик, сделайте это.)
о, никогда не упоминалось. Я думал, что у вас есть "&" при передаче.





Массивы передаются как указатели - нет необходимости передавать на них ссылку. Если вы заявляете, что ваша функция:
void pushSynonyms(string synline, char matrizSinonimos[][1024]);
Ваши изменения в массиве сохранятся - массивы никогда передаются по значению.
Когда у вас есть matrizSinonimos [1024] [1024] в параметрах вашей функции ar в качестве переменной внутри main (), вы выделяете 1 МБ памяти в стеке. Стек обычно большой, но он чрезмерный. Объявите фактический массив статическим и передайте указатель.
@Arkadiy: Я пробовал: 'char static matrizSinonimos [10] [10]; char указатель = & matrizSinonimo; ' Ошибка компиляции: невозможно преобразовать char [] [10] [10] в char при инициализации.
Однако в списках параметров Harper, char matriz Sinonimos [1024] [1024] и char matriz Sinonimos [] [1024] одинаковы. Я должен вас неправильно понять.
@dmindreader: char foo [10] [10] не является символом *, это символом **. Если вы хотите передать массив с этим синтаксисом, вы должны объявить: void pushSynonyms (string synline, char ** matrizSinonimos); . Обычно объявление с элементом-указателем принимает параметры длины для каждого измерения, чтобы избежать ошибок.
"char * указатель = & matrizSinonimo;" не годится. Вам действительно нужно узнать, как многомерные массивы представлены в C. x [10] [10] - это не указатель на char, это указатель на массив блоков по 10 символов в каждом. Используйте char ptr [] [10] = matrix; «ptr» здесь - указатель на неопределенное количество блоков из 10 символов.
(упс, «это указатель на массив блоков по 10 символов каждый» следует заменить на «это массив блоков по 10 символов в каждом»)
(редактировать 1) Я забыл ответить на ваш актуальный вопрос. Что ж: после того, как вы исправили код, чтобы передать массив правильным образом (больше нет неправильного косвенного обращения), мне кажется наиболее вероятным, что вы неправильно проверили свои входные данные. Вы читаете из потока, сохраняете его в векторе, но никогда не проверяли, действительно ли все числа, которые вы получаете, находятся в правильном диапазоне. (конец редактирования 1)
Первый:
Использование необработанных массивов может быть не тем, что вам нужно. Есть std::vector или boost::array. Последний представляет собой массив фиксированного размера времени компиляции, такой как необработанный массив, но предоставляет определения типов и методы коллекции C++, которые практичны для универсального (читай: шаблонного) кода.
И, используя эти классы, может быть меньше путаницы с безопасностью типов, передачей по ссылке, по значению или передачей указателя.
Второй: Массивы передаются как указатели, сам указатель передается по значению.
В третьих: Такие большие объекты следует размещать в куче. Накладные расходы на выделение кучи в таком случае незначительны, и это уменьшит вероятность нехватки места в стеке.
Четвертый:
void someFunction(int array[10][10]);
на самом деле:
(редактировать 2) Спасибо за комментарии:
void someFunction (int ** массив);
void someFunction(int (*array)[10]);
Надеюсь, я не облажался в другом месте .... (конец редактирования 2)
Информация о типе массива 10x10 теряется. Чтобы понять то, что вы, вероятно, имели в виду, вам нужно написать:
void someFunction(int (&array)[10][10]);
Таким образом, компилятор может проверить, действительно ли массив на вызывающей стороне является массивом 10x10. Затем вы можете вызвать функцию следующим образом:
int main() {
int array[10][10] = { 0 };
someFunction(array);
return 0;
}
void someFunction (int array [10] [10]) действительно void someFunction (int ( array) [10]). Вы можете проверить это с помощью MSVC или онлайн-компилятора C++ Comeau.
вы оба неправы. void someFunction (int array [10] [10]); является недействительным someFunction (int (массив) [10]); :) gimpf ваш ответ был совершенно правильным, пока вы не сказали «void someFunction (int array [10] [10]); действительно void someFunction (int * array); "
Исключением, вероятно, является 0xC00000FD или переполнение стека!
Проблема в том, что вы создаете в стеке массив размером 1 МБ, который, вероятно, слишком велик.
Код в том виде, в котором он есть, - я не могу найти ошибку. Единственная проблема, которую я заметил, заключается в том, что если вы вообще не укажете номер, эта часть нанесет вред:
(synsAux.size()-1)
Он вычитает единицу из 0u. Это будет продолжаться, потому что size() возвращает беззнаковый целочисленный тип. В итоге вы получите очень большое значение, где-то около 2 ^ 16 или 2 ^ 32. Вы должны изменить все условие while на
while ((index+1) < synsAux.size())
Вы можете попробовать поискать ошибку на стороне вызова. Часто бывает, что где-то до этого происходит переполнение буфера или повреждение кучи, и в результате этого на более позднем этапе программы происходит сбой.
Что касается массива и того, как он передается, я думаю, у вас все хорошо. Хотя вы все равно передаете массив по значению. Может быть, вы это уже знаете, но я повторю. Вы действительно передаете указатель на первый элемент этого массива:
char matrizSinonimos[1024][1024];
Двумерный массив на самом деле представляет собой массив массивов. Первый элемент этого массива - это массив, а указатель на него - это указатель на массив. В этом случае это
char (*)[1024]
Несмотря на то, что в списке параметров вы сказали, что принимаете массив массивов, компилятор, как всегда, корректирует это и делает его указателем на первый элемент такого массива. Итак, на самом деле ваша функция имеет прототип после того, как компилятор настроил типы аргументов:
void pushSynonyms (string synline, char (*matrizSinonimos)[1024]);
Хотя часто предлагается, Вы не можете передать этот массив как char**, потому что вызываемой функции требуется размер внутреннего измерения, чтобы правильно адресовать подразмеры при правильных смещениях. Работая с char** в вызываемой функции, а затем записывая что-то вроде matrizSinonimos[0][1], он попытается интерпретировать первые символы sizeof (char **) этого массива как указатель и попытается разыменовать случайную ячейку памяти, а затем сделает это во второй раз, если между ними не произойдет сбой. Не делай этого. Также не имеет значения, какой размер вы указали во внешнем измерении этого массива. Это рационализировало. Теперь передавать массив по ссылке не очень важно. Но если вы хотите, вы должны все изменить на
void pushSynonyms (string synline, char (&matrizSinonimos)[1024][1024]);
Передача по ссылке не передает указатель на первый элемент: все размеры всех измерений сохраняются, и передается сам объект массива, а не значение.
Это здорово, но это не совсем касается сбоя, который происходит на сайте вызова функции.
Я думаю, ему лучше сосредоточиться на коде, связанном с вызовом. Я думаю, что ошибка может быть вызвана переполнением буфера или чем-то подобным.
попробуйте объявить это как:
void pushSynonyms (const string & synline, char *matrizSinonimos[1024] )
Я верю, что это сделает то, что вы хотите. То, как у вас это есть, как говорили другие, создает в стеке массив размером 1 МБ. Кроме того, изменение синлайн с string на const string & исключает помещение полной копии строки в стек.
Кроме того, я бы использовал какой-то класс для инкапсуляции matrizSinonimos. Что-то вроде:
class ms
{
char m_martix[1024][1024];
public:
pushSynonyms( const string & synline );
}
тогда вам вообще не нужно его сдавать.
Я не понимаю, что не так с приведенным выше кодом, но если вы не можете заставить синтаксис массива работать, вы всегда можете сделать это:
void pushSynonyms (string synline, char *matrizSinonimos, int rowsize, int colsize )
{
// the code below is equivalent to
// char c = matrizSinonimos[a][b];
char c = matrizSinonimos( a*rowsize + b );
// you could also Assert( a < rowsize && b < colsize );
}
pushSynonyms( "1 7", matrizSinonimos, 1024, 1024 );
Вы также можете заменить rowize и colsize на #define SYNONYM_ARRAY_DIMENSION 1024, если он известен во время компиляции, что ускорит шаг умножения.
Какую ошибку это дает?