2016-12-03 3 views
0

Я искал, и я не нашел ничего такого, как моя ситуация. У меня есть float**, и я знаю, что это особый тип указателя, потому что это массив элементов, которые имеют float*, который указывает на другую зону памяти. Поэтому я пишу простой код для определения длины этой матрицы, а точнее длину float + элементов внутри float**; Но это приводит к ошибке сегментации. Здесь мой код:Длина указателя указателя

int Loader:: Length(float** length) 
{ 
    int count=0; 
    while(*length[count]!='\0'){ 
     count++; 

    } 
    std::cout<<count<<std::endl; 
    return count; 

} 

Извините за мой английский и извиняюсь за глупый вопрос. Спасибо всем.

+0

Примечание: '**' не является «двойным указателем», а «указателем на указатель». «Двойной указатель» обычно понимается как «double *». –

ответ

2

У меня есть float** и я хорошо знаю, что это особый тип указателя

Не совсем. Двойной указатель - это особый случай единственного указателя. Он по-прежнему является указателем на T, а T - float*.

, потому что это массив элементов

Нет! Это is не массив. Он может указывать на первый элемент массива.

которые имеют поплавок *, который указывает на другую зону памяти.

Точнее, float** может указывать на первый элемент массива, полный float*. Там, где эти индивидуумы указывают на другую историю.

Итак, я пишу простой код для определения длины этой матрицы,

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

То есть, если у вас есть конвенции для последнего элемента, как строки в стиле С или строковых литералов с их '\0' терминатора. Это подводит нас к следующему пункту ...

int Loader:: Length(float** length) 
{ 
    int count=0; 
    while(*length[count]!='\0'){ 

Вот преступник. Не все массивы завершаются '\0'. На самом деле, это не типично для произвольных массивов, содержащих разделитель нуля.

Так что если массив, чей первый элемент length указывает на фактический элемент, который сравнивается с '\0', то ваш цикл пройдет один элемент за конец массива и попытается прочитать оттуда. В этот самый момент вызывается неопределенное поведение, и ваша программа может делать что угодно, включая случайные сбои.


Лучшее решение для вашей проблемы заключается в использовании std::vector, потому что std::vector всегда знает свой собственный размер. Так что сделайте это std::vector<float*>. Или еще лучше, std::vector<std::vector<float>>.

Фактически, если это действительно матрица, то сделайте это std::vector<float>, сохраните все содержимое смежно, дополнительно сохраните ширину матрицы где-нибудь и всегда вычисляйте смещение для X/Y.

+0

Спасибо, наконец, я понимаю. Спасибо endeed;) –

2

Проблема вызвана вашим ожиданием того, что все массивы работают так же, как буквальные строки символов, т. Е. Что они автоматически заканчиваются значением 0. Ни C++, ни C не работают так.

Если вы хотите длину массива необходимо выполнить одно из следующих действий:

  1. Пропустите длину вместе с массивом везде.
  2. Используйте std :: vector, std :: deque или std :: array вместо массива и получите длину от этого.
+0

нормально, но мне любопытно .. почему он возвращает segmentation fault, когда я trid для доступа к элементам? (* length [count]) –

+1

@ P.Carlino Потому что в какой-то момент вы попытаетесь получить доступ к адресу памяти, который вы не зарезервировали, и ОС будет жаловаться. –

+0

, но он зарезервирован ... с длиной [num1] [num2] работает –

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