2015-01-17 4 views
0

Если подпрограмма выделяет новый буфер, как вызывающий объект этой функции передает указатель для получения адреса?Как передать указатель по ссылке в C++

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

int main() 
{ 
    float *fMyBuffer; 

    // Pointer Update 
    readFloatData (fMyBuffer); // &fMyBuffer *fMyBuffer 

    // Deallocate Memory 
    delete [] fMyBuffer; 
} 


void readFloatData(float *&fBuffer) //*fBuffer &fBuffer 
{ 
    // Create New Buffer 
    float *fData; 
    fData = new float [1000]; 

    // Pass our buffer Address to user's pointer 
    fBuffer = fData; 

}

+0

Если ссылка на 'float' является' float * ', то ссылается на' float * '? – SJuan76

+0

@Sjuan Обычно невероятно плохая идея? :-) – Voo

+0

Очень просто: 1) подпись функции: 'void readFloatData (float ** fBuffer) {...}', 2) вызов функции: 'readFloatData (& fMyBuffer);', 3) Удалить все (теперь посторонние) в файле readFloatData() :. – FoggyDay

ответ

1

Это обычно делается путем пропускания двойного указателя, или реальный ++ путем C является использование std::unique_ptr или std::vector:

вектор:

int main(int argc, char** argv) 
{ 
    std::vector<float> fMyBuffer = readFloatData(); 
    return 0; 
} 


std::vector<float> readFloatData() 
{ 
    // Create New Buffer 
    std::vector<float> fData(1000); 

    // Populate vector... 

    return fData; 
} 

unique_ptr:

int main(int argc, char** argv) 
{ 
    std::unique_ptr<float[]> fMyBuffer = readFloatData(); // Note the [] is MUST else the wrong deleter will be used 
    return 0; 
} 


std::unique_ptr<float[]> readFloatData() 
{ 
    // Create New Buffer 
    std::unique_ptr<float[]> fData(new float[1000]); 

    // Populate data... 

    return fData; 
} 

двойного указателя :

int main(int argc, char** argv) 
{ 
    float* fMyBuffer = nullptr; 
    readFloatData(&fMyBuffer); 
    delete[] fMyBuffer; 
    return 0; 
} 


void readFloatData(float** fData) 
{ 
    if (fData) 
    { 
     // Create New Buffer 
     *fData = new float[1000]; 

    // Populate data... 
    } 
} 

И как Konrad Rudolph сказал, ссылка на указатель можно также:

int main(int argc, char** argv) 
{ 
    float* fMyBuffer = nullptr; 
    readFloatData(fMyBuffer); 
    delete[] fMyBuffer; 
    return 0; 
} 


void readFloatData(float*& fData) 
{ 
    // Create New Buffer 
    fData = new float[1000]; 
} 

Обратите внимание, что вы можете также передать ссылки на векторы или unique_ptrs, например:

void readFloatData(std::unique_ptr<float[]>& fData) 
void readFloatData(std::vector<float>& fData) 
+0

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

+0

Да, я думаю, я тоже добавлю, что слишком – paulm

+0

Ссылка на пример указателя - это то, что я имел в виду, тот факт, что явное назначение еще не круче! Как некоторые уже отмечалось, исходный код должен работал, но я goofed интерпретации адресация .. отладчик показывает FData @ 0x28fe24: 0x3d6f460 , который я принял, чтобы означать буфер в 0x28fe24 ... то при возврате функции мой указатель fMyBuffer был установлен в 0x3d6f460, а не 0x28Fe24. – ben

1

Используйте указатель двойной уровень?

float **fBuffer будет работать нормально.

+1

Вы можете это сделать, но вы не Не нужно. –

+2

Использование двойного указателя - плохой совет, так как его не очень идиоматический C++ – paulm

0

Your code actually works as-is (кроме тот факт, что вам необходимо объявить readFloatData перед его использованием). Вопрос в том, действительно ли это хорошая идея - почему бы не вернуть новое значение вместо этого? Это то, за что возвращают значения:

float* readFloatData() 
{ 
    // Create New Buffer 
    float *fData = new float [1000]; 

    // Pass our buffer Address to user's pointer 
    return fData; 
} 

int main() { 
    float* fMyBuffer = readFloatData(); 
    // … 
    delete [] fMyBuffer; 
} 

Это означает, что необработанные указатели не должны иметь собственной памяти. Используйте вместо этого std::unique_ptr или аналогичный. Для массивов используйте std::vector<float> вместо указателя на массив.

+1

Это не «как есть», точно. Вы переехали, что, возможно, было оригинальной проблемой. –

+0

@Ben Справедливая точка, я внесла поправки. Тем не менее, описание OP определенно похоже на составленный код и просто что-то неожиданное. Поэтому я уверен, что это была не оригинальная проблема. –

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