Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
AndZhel
0 / 0 / 0
Регистрация: 04.05.2015
Сообщений: 7
1

При передаче указателя в качестве аргумента функции теряется значение

04.05.2015, 14:29. Просмотров 657. Ответов 13
Метки нет (Все метки)

Добрый день.
Есть простенькая задачка сделать связанный список. При этом создается первый эелемнт списка с нулевым указателем на следующие элемент. Потом необходимо получить элемент списка (взять значение с клавы) потом вставить этот элемент в список (найти нулевую ссылка на следующий и присвоить), потом вывести. Споткнуля на вставке. При передаче в insert указателя на полученную структуру - указатель хоть адрес и не меняет ссылается на мусор - в чем бок не могу понять.
Код
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "stdafx.h"
#include <iostream>
using namespace std;
 
struct Element{
    char *imie;
    Element* next;
};
 
Element *list = new Element;
 
Element *getNewElement(){
    char name[80];
    Element newElement;
    cout << "Insert name of element:";
    cin >> name;
    newElement.imie = name;
    newElement.next = 0;
    return &newElement;
};
 
void insert(Element *element){
    Element *p = list;
    while (p->next != NULL) p++;
    p->next = element;
};
 
void show(){
    Element *p = list;
    cout << "Elements: " << endl;
    while (p->next != NULL){
        cout << p->imie << endl;
        p++;
    };
};
 
int main()
{
    list->next = 0;
    list->imie = "0";
    Element newElement;
    while (true){
        newElement = *getNewElement();
        insert(&newElement);
        show();
    }
 
    system("pause");
    return 0;
}
Добавлено через 2 минуты
дебагером в строке 22 element показывает все нормально. в 23-й уже мусор.
Всем спасибо за помощь и терпение.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.05.2015, 14:29
Ответы с готовыми решениями:

При передаче аргумента в функцию каким из ниже приведенных способов его изменение в функции повлияет на его значение в остальной части программы
1. По указателю 2. По классу 3. По значению 4. По оператору 5. По ссылке

Ошибка при вызове функции transform с функцией, в качестве аргумента
Здравствуйте! Хочу перевести строку в нижний\верхний регистр, используя...

Теряется строка при передаче в функцию
Привет Замучался копать уже. Теряется строка при передаче её в функцию. Код...

Использование указателя при передаче параметра
Добрый вечер! Надо оформить функцию &quot;LoadTexture&quot;. Вот задачка:...

Порча указателя при передаче в функцию
Добрый вечер. Проблема такая - при передаче в функцию структуры, полем...

13
nmcf
6274 / 5577 / 2537
Регистрация: 14.04.2014
Сообщений: 23,468
04.05.2015, 14:50 2
В getNewElement() у тебя ошибка, возвращаешь указатель на локальную структуру.
Все элементы должны создаваться через new. Поле imie тоже должно быть через new, константу присваивать нельзя. 10-ю строку перенеси в main().
1
AndZhel
0 / 0 / 0
Регистрация: 04.05.2015
Сообщений: 7
04.05.2015, 20:11  [ТС] 3
Спасибо.
Изначально все делал через new. С полем imie не совсем понял. Можно как для тех "кто на бронепоезде" - пример?
Если 10-ю строку перенесу в main видимость списка поменяется и в строка 23, 29 он будет недоступен.
Проблема если даже сделаю new и в getNewElement() перепишу на

Добавлено через 16 секунд
C++ (Qt)
1
2
3
4
5
6
7
8
9
Element *getNewElement(){
    char name[80];
    Element *newElement = new Element;
    cout << "Insert name of element:";
    cin >> name;
    newElement->imie = name;
    newElement->next = 0;
    return newElement;
};
остается
0
lss
930 / 859 / 355
Регистрация: 10.10.2012
Сообщений: 2,705
04.05.2015, 20:37 4
Цитата Сообщение от AndZhel Посмотреть сообщение
С полем imie не совсем понял.
Ты, этому уазателю, присвоил адрес строковго литерала (зачем?), потом присваиваешь ему адрес локального массива (char name[80]). Под imie нужно динамически выделить память:
C++
1
list->imie = new char[80];
В getNewElement() копировать (через stfcpy()) туда массив name, или сразу делать ввод в imie.
1
AndZhel
0 / 0 / 0
Регистрация: 04.05.2015
Сообщений: 7
04.05.2015, 21:25  [ТС] 5
Всем спасибо!
В итоге следующий код отработал так как нужно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
include "stdafx.h"
#include <iostream>
using namespace std;
 
struct Element{
    char *imie;
    Element* next;
};
 
Element *list = new Element;
 
Element *getNewElement(){
    Element *newElement = new Element;
    newElement->imie = new char;
    newElement->next = 0;
    cout << "Insert name of element:";
    cin >> newElement->imie;
    return newElement;
};
 
void insert(Element *element){
    Element *p = list;
    while (p->next) p = p->next;
    p->next = element;
};
 
void show(){
    Element *p = list;
    cout << "Elements: " << endl;
    do {
        cout << p->imie << endl;
        p = p->next;
    } while (p);
};
 
int main()
{
    list->next = 0;
    list->imie = "0";
    while (true){
        Element *newElement = getNewElement();
        insert(newElement);
        show();
    }
    system("pause");
    return 0;
}
0
lss
930 / 859 / 355
Регистрация: 10.10.2012
Сообщений: 2,705
04.05.2015, 21:28 6
Цитата Сообщение от AndZhel Посмотреть сообщение
newElement->imie = new char;
Один символ будет храниться?
0
AndZhel
0 / 0 / 0
Регистрация: 04.05.2015
Сообщений: 7
04.05.2015, 21:40  [ТС] 7
ну я так понял new возвращает указатель на первый символ. во всяком случае компилятор VS отработал корректно.
0
lss
930 / 859 / 355
Регистрация: 10.10.2012
Сообщений: 2,705
04.05.2015, 22:15 8
Цитата Сообщение от AndZhel Посмотреть сообщение
ну я так понял new возвращает указатель на первый символ
На первый и единственный, под который выделена память.
Цитата Сообщение от lss Посмотреть сообщение
Один символ будет храниться?
0
AndZhel
0 / 0 / 0
Регистрация: 04.05.2015
Сообщений: 7
04.05.2015, 22:45  [ТС] 9
в show инструкция "cout << p->imie" выводит все символы введеные с консоли - не первый а все
0
lss
930 / 859 / 355
Регистрация: 10.10.2012
Сообщений: 2,705
04.05.2015, 22:57 10
Цитата Сообщение от AndZhel Посмотреть сообщение
в show инструкция "cout << p->imie" выводит все символы введеные с консоли - не первый а все
И что с того? Куда читаешь, если память не выделил? Сделай delete p->imie, увидишь результат.
1
AndZhel
0 / 0 / 0
Регистрация: 04.05.2015
Сообщений: 7
05.05.2015, 01:16  [ТС] 11
Спасибо, верю, но попробую таки сделать. Надеюсь система не крэшниться

Добавлено через 2 минуты
и в догонку... а если длина строки не известна? как выделить достаточно памяти?
0
lss
930 / 859 / 355
Регистрация: 10.10.2012
Сообщений: 2,705
05.05.2015, 01:27 12
Цитата Сообщение от AndZhel Посмотреть сообщение
но попробую таки сделать.
Что сделать? Кривой код?
Цитата Сообщение от AndZhel Посмотреть сообщение
а если длина строки не известна? как выделить достаточно памяти?
Есть такой класс: string. Автоматически управляет памятью.

Добавлено через 6 минут
Если без string, то выдели память с запасом, прочитай туда строку, определи длину, выдели другую память под размер строки (не забудь про память под '\0'), скопируй туда строку, первую память освободи (или сделай её изначально локальной, чтобы автоматически освободилась после выхода из функции).
0
AndZhel
0 / 0 / 0
Регистрация: 04.05.2015
Сообщений: 7
05.05.2015, 10:39  [ТС] 13
Цитата Сообщение от lss Посмотреть сообщение
Что сделать? Кривой код?
Да нет, кривой код не хочется - я имел в виду посмотреть что будет если деструктор вызвать.
0
lss
930 / 859 / 355
Регистрация: 10.10.2012
Сообщений: 2,705
05.05.2015, 15:35 14
Цитата Сообщение от AndZhel Посмотреть сообщение
я имел в виду посмотреть что будет если деструктор вызвать.
Посмотрел?
Цитата Сообщение от AndZhel Посмотреть сообщение
ну я так понял new возвращает указатель на первый символ. во всяком случае компилятор VS отработал корректно.
Компиляторы не отслеживают выход за границу выделенной памяти. Это UB, может проявляться при работе, может нет, зависит от разных обстоятельств. Попробуй, например, строку подлиннее ввести, символов 50, может и без освобождения испорченной памяти увидишь ошибку.
0
05.05.2015, 15:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.05.2015, 15:35

Найти наименьшее значение функции и значение аргумента, при котором оно получено
Для заданного набора коэффициентов a, b, c, d найдите наименьшее значение...

При передачи указателя на обьект ошибка,а при передаче ссылки на указатель нет. Почему?
Hi All! class SomeObj { public: int x; }

Ошибки преобразования при передаче указателя на функцию
Есть функция SQLITE_API int SQLITE_STDCALL sqlite3_exec( sqlite3*, ...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru