2013-11-01 3 views
1
void nothing(int* buffer) 
    { 
     int* temp = new int[5]; 
     for (int i = 0; i < 5; i++) 
     { 
      temp[i] = i; 
     } 
     buffer = temp; 
    } 

    void main(int argc, char* argv[]) 
    { 
     int* a = new int; 
     nothing(a); 
     for (int i = 0; i < 5; i++) 
     { 
      cout << a[i] << endl; 
     } 
     system("pause"); 
    } 

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

выход:

-842150451 
-33686019 
-1414812757 
-1414812757 
0 

ожидается:

0 
1 
2 
3 
4 
+0

См. [this] (http://stackoverflow.com/questions/ 4426474/is-through-pointer-argument-pass-by-value-in-c) вопрос и соответствующий ответ. – crayzeewulf

ответ

3

Вам необходимо пройти через указатель на указатель (или как другие указали ссылку на указатель), т.е. int **, а затем назначить с помощью *buffer = temp и с помощью nothing(&a).

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

Однако, я рекомендую вам использовать зЬй :: вектор вместо:

void nothing(std::vector<int> &buffer) { 
    ... 
} 

int main(int argc, char* argv[]) 
{ 
    std::vector<int> a; 
    nothing(a); 
    for (int i = 0; i < 5; i++) 
    { 
     cout << a[i] << endl; 
    } 
    system("pause"); 
    return 0; 
} 

В зависимости от сценария вы можете захотеть изменить функцию ничего в функции стиля инициализации, то есть возвращение объекта напрямую :

std::vector<int> nothing() { 
    std::vector<int> temp; 
    // fill vector here 
    return temp; 
} 

int main(int argc, char* argv[]) 
{ 
    auto a = nothing(); 
    for (int i = 0; i < 5; i++) 
    { 
     cout << a[i] << endl; 
    } 
    system("pause"); 
    return 0; 
} 

Это намного больше C++ - ish и не позволяет вам обрабатывать удаление массива вручную.

Для фактического генерирования данных в векторе взгляните на Initialization of std::vector<unsigned int> with a list of consecutive unsigned integers .

0

a передается по значению ни к чему, поэтому изменение его копии ничем не влияет на a. Вам придется пройти, если по ссылке или, как говорит @villintehaspam, передать указатель на указатель.

0

«Я пытаюсь передать массив (указатель), чтобы функционировать и изменять его в»

Но что ваш код делает то, что он выделяет память для 1 int, передает указатель на эту память к вашей функции и вашей функции выделяет массив и пытается назначить адрес или этот вновь выделенный массив переданному указателю, то есть он пытается изменить сам указатель.

Попробуйте пройти int** вместо int* и пусть вызывающему сделать:

int* a; 
nothing(&a); 

Также отметим, что в C++ это должно быть довольно редкость, чем обычная практика, что функция динамически выделяет некоторые ресурсы и бросает нагрузку в форма ответственности за освобождение этих ресурсов (даже используя определенные средства, в этом случае вызывающий delete[]) вызывающему абоненту. Подумайте об использовании STL-контейнеров, таких как std::vector, или в случае, если вы должны придерживаться массивов в стиле C, то, по крайней мере, предпочитаете те, у которых есть время автоматического хранения.

0

temp - локальная переменная, объявленная внутри ничего(). Это означает, что память для temp теряется, когда ничего() не возвращается. Вы не можете получить данные обратно из локальной переменной - отсюда мусор.

+0

Проблема не в том, что temp - это локальная переменная, потому что значение в temp копируется в буфер. является то, что буфер * lso * - локальная переменная. –

0

Указатель buffer передается по значению (что является значением по умолчанию в C++), а это значит, что создается копия. Затем вы изменяете эту копию. Это время с ++, вы можете передать ссылку вместо:

void nothing(int*& buffer) 

Таким образом, исходный объект передается, а не копию.

1

Важная прелюдия: Если вы можете использовать vector вместо массивов/указателей. Мы все будем поощрять это как можно больше! Вполне возможно, что вы можете программировать несколько месяцев подряд, написав довольно сложное программное обеспечение и никогда не должны звонить new или delete и не должны беспокоиться обо всех этих неприятных проблемах C.


Просто прекратите использовать temp!

void nothing(int* buffer) 
{ 
    for (int i = 0; i < 5; i++) 
    { 
     buffer[i] = i; 
    } 
} 

Это займет, как вход, указатель на ваш массив. Затем он будет писать непосредственно в этот массив.

Ваш предыдущий код создал второй массив. Каждый раз, когда вы вызываете new, вы получаете новый массив. int* temp = new int[5];. Для этого подхода к работе вам нужно будет скопировать данные в массиве temp в массив буфера. Но вы не можете копировать массивы (легко) в C.

buffer = temp; // This *doesn't* copy any array 

Эта строка ничего не сделала. Эти два массива все еще существуют, и в результате этого данные не были скопированы. Здесь была изменена локальная переменная, называемая buffer; но изменение было незначительным - буфер, используемый для указания на старый массив, и теперь он указывает на новый массив. И потому, что буфер был локальная переменная, она потеряла всякий смысл, как только функция возвращается (это указал на нелокальных данных, но сам buffer указатель остается локальным.

В коротышка, оригинал nothing функция сделал ничего полезного: он создал новый массив, поместил в него некоторые значения, затем проигнорировал его. Буферная переменная внутри main не повлияла на вашу функцию.

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