Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/25: Рейтинг темы: голосов - 25, средняя оценка - 4.68
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99

Запись значения в динамический массив

18.08.2011, 00:37. Показов 5376. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер,
Сел я на ночь глядя писать программу, но вот проблема
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int s=0,k=0,z=0;
  char *temp = new char[s];
  char *tempnum = new char[k];
  int  *tempnum3 = new int[s+1];
  for(int i=0; i < size; i++)
  {
      switch(A[i])
      {
          case '+': case '-': case '/': case '*': 
          *(temp+s)=*(A+i);
          *(tempnum+k)='.';
          k++;
          s++;
          z=0;
          break;
          case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
          *(tempnum+k)=*(A+i);
          k++;
          z++;
          *(tempnum3+s+1) = z ;
          break;
      }
  }
в tempnum3 у меня не пишется значения z.
Заранее спасибо!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.08.2011, 00:37
Ответы с готовыми решениями:

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

Запись слова в динамический массив
помогите пожалуйста, пользователь вводит слово, надо записать это слово по буквам в массив (1 буква, одна ячейка массива) , как определить...

Запись данных в динамический массив
Цель программы: принимать от пользователя ,не ограниченное количество раз, числа типа float и записывать их в динамический массив. Так ,...

18
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 00:49
*(tempnum3+s+1) -- это Вы уже не в массив пишете.

tempnum3 изначально содержит адрес элемента tempnum3[0]. tempnum3[s+1] -- это уже за границами массива. Последний элемент -- это tempnum3[s]: учитывайте, что вы выделили память под s+1 элементов, включая нулевой. Соответственно, указатель на последний элемент --- это tempnum3 + s.

P.S. И не забывайте смещать указатель, а то у вас в цикле s не меняется и получается, что пишете в один и тот же элемент.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:01  [ТС]
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int s=0,k=0,z=0;
  char *temp = new char[s];
  char *tempnum = new char[k];
  int  *tempnum3 = new int[s+1];
  for(int i=0; i < size; i++)
  {
          switch(A[i])
          {
                  case '+': case '-': case '/': case '*': 
                  *(temp+s)=*(A+i);
                  *(tempnum+k)='.';
                  k++;
                  s++;
                  z=0;
                  break;
                  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8':     case '9':
                  *(tempnum+k)=*(A+i);
                  k++;
                  z++;
                  *(tempnum3+s) = z ;
                  break;
          }
  }
то есть так?
P.S. s у меня меняет значения мне просто нужно написать одно z и все
0
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:08
Если Вы хотите на каждом шаге цикла писать z в последний элемент массива tempnum3, то, да
C++
1
*(tempnum3+s) = z ;
--- то, что нужно.
Остальная логика программы мне не совсем понятна. Например, я раньше нигде не видел подобного синтаксического описания конструкции switch - case
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:10  [ТС]
Я просто пишу калькулятор который обрабатывает данные в момент ввода
Это просто кусок Огросного кода с праработанным арифметическим синтаксисом и т.д.


________________________________________ _______________________________________

Почему-то проблема осталась и все равно не пишется значение z.
0
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:23
В общем, чисто новичковское имхо:
char *tempnum3 = new char[s+1]; при s = 0 выделяет место под один int. Соответственно, указатель tempnum3+s при s, отличных от нуля, указывает уже не на массив. Валидным будет лишь указатель tempnum3.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:31  [ТС]
То есть как правильно написать?
0
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:43
Ну по сути что происходит: Вы устанавливаете s = 0 и выделяете память под s+1 == 1 элемент:
C++
1
int  *tempnum3 = new int[s+1];
Потом в цикле делаете работу и при каком-то case пишете по адресу tempnum3+s+1 == tempnum3 + 1 значение z. При этом z пишется за границей массива.
Поправьте
C++
1
*(tempnum3+s+1) = z ;
на
C++
1
*(tempnum3+s) = z ;
и поставьте там breakpoint --- вполне возможно, что Вы до этой строчки не доходите в силу логики своего цикла.

Добавлено через 2 минуты
Хочу добавить, что при s == 0 запись tempnum3+s равносильна просто tempnum3. Если Вы изменяете s после строчки
C++
1
int  *tempnum3 = new int[s+1];
на отличное от нуля значение, а потом пытаетесь обратиться к s-тому элементу массива, то это неправильно --- массив был выделен под 1 элемент.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:44  [ТС]
Поправил, точнее я и так это сделал, но все равно не идет запись
0
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:49
Вы уверены, что код доходит до этой строчки, а не обрубается на ложности проверок case'ов?
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:51  [ТС]
вроде доходит, вот полный код
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// calculator.cpp : main project file.
 
#include "stdafx.h"
#include <conio.h>
#include <iostream>
 
using std::cout;
using std::cin;
using std::endl;
 
using namespace System;
 
int function(char A[], int size) //считает кол-во цифр и символов
{ int s=0,k=0,z=0;
  char *temp = new char[s];
  char *tempnum = new char[k];
  int  *tempnum3 = new int[s+1];
  for(int i=0; i < size; i++)
  {
      switch(A[i])
      {
          case '+': case '-': case '/': case '*': 
          *(temp+s)=*(A+i);
          *(tempnum+k)='.';
          k++;
          s++;
          z=0;
          break;
          case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
          *(tempnum+k)=*(A+i);
          k++;
          z++;
          *(tempnum3+s) = z ; 
          break;
      }
  }
  /*for(int i=0; i < s+1; i++)
  {
      while(*(tempnum+k)!='.')
      {
 
      }
  }*/
  return s;
  delete []temp;
  delete []tempnum;
  delete []tempnum3;
}
int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Hello World");
    
    char ch;
    char *numbers;
    numbers = 0;
    int i=0;
    bool good = true, back = false, zero = false, symbol = true;
 
    do
    {
        ch = getch();
        switch(ch)
        {
            case '0':   case '1':   case '2': case '3': case '4': case '5': case '6':   case '7':   case '8':   case '9':   case '-':
            case '+':   case '=':   case '.': case '(': case ')': case '/': case '*':
                
            if(i==0)
            {
                numbers = new char [i+3];
                *numbers = ch;
                *(numbers+1) = '\0';
                cout << ch;
                i++;
            }
            else
            {
                if(i>2)
                {
                    switch(*(numbers+i-2))
                    {
                        case '-': case '+':     case '=':   case '.': case '/': case '*':
                            back = true;
                            if(*(numbers+i-2) == '/')
                                zero = true;
                            else
                                zero = false;
                            break;
                        default:
                            back = false;
                    }
                }
                if(i==1 && numbers[0] == '0' || back && *(numbers+i-1) == '0')
                {
                    switch(ch)
                    {
                        case '-': case '+':     case '=':   case '.': case '/': case '*':
                            good = true;
                            if(zero == true && ch != '.')
                            {
                                good = false;
                                cout << endl;
                                cout << "Divide by zero!!!";
                                cout << endl << numbers;
                            }                       
                            break;
                        default:
                            cout << endl;
                            cout << "Mistake in symbol";
                            cout << endl << numbers;
                            good = false;
                    }
                }
 
                    
        for(int k = 0; k < 6; k++) //два символа
    {
                if(*(numbers+i-1) == k+42)
                {
                    switch(ch)
                    {
        case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '(': good = true; break;
        default:
            cout << endl;
            cout << "Mistake in symbol";
            cout << endl << numbers;
            good = false;
                    }
                }
            }
        if(*(numbers+i-1) == '(') // открытая скобка
        {
            switch(ch)
            {
       case '0': case '1': case '2': case '3':  case '4': case '5': case '6': case '7': case '8': case '9': good = true; break;
       default:
            cout << endl;
            cout << "Mistake in symbol";
            cout << endl << numbers;
            good = false;
            }
        }
        if(*(numbers+i-1) == ')') //закрытая скобка
        {
            switch(ch)
            {
     case '+': case '=': case '/': case '*': good = true; break;
       default:
            cout << endl;
            cout << "Mistake in symbol";
            cout << endl << numbers;
            good = false;
            }
        }
                
        for(int j = 0; j < 6; j++) // скобки
    {
                if(*(numbers+i-1) == j+48)
                {
                    switch(ch)
                    {
        case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-':
        case '+': case '=': case '.': case '/': case '*': case ')':good = true; break;
        default:
            cout << endl;
            cout << "Mistake in symbol";
            cout << endl << numbers;
            good = false;
                    }
                }
            }
 
 
 
                if(good)
                {
                    char *temp = new char[i];
                    for(int k =0; k < i; k++)
                    *(temp+k) = *(numbers+k);
                    delete []numbers;
                    numbers = 0;
                    numbers = new char [i+3];
                    for(int k =0; k < i; k++)
                    *(numbers+k) = *(temp+k);
                    delete [] temp;
                    *(numbers+i) = ch;
                    *(numbers+i+1) = '\0';
                    good = true;
                    cout << ch;
                    i++;
                }
                
            }
 
            break;
        default:
            cout << endl;
            cout << "Mistake in symbol";
            cout << endl << numbers;
        }
 
    }while(ch != '=' && ch != '\0');
 
    cout << endl;
    Console::WriteLine(L"Hello World");
    cout << endl;
    if(numbers!=0)
    {
        cout << numbers;
    }
 
    cout << endl;
    Console::WriteLine(L"Hello World");
 
    //cin >> ch;
    cout << function(numbers,i);
    cout << " symbols here";
    cout << endl;
    //cout << ch;
    if( numbers !=0 )
        delete []numbers;
    cin >> ch;
    return 0;
}
Извеняюсь за hello world, я кое-что тестировал
0
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 02:01
Короче, вся проблема в том, что Вы выделяете некорректное количество памяти.
C++
1
char *tempnum = new char[k==0];
, к примеру, выделит минимальный блок памяти (точный размер не знаю). И это не будет массивом --- неизвестно количество элементов. Просто кусок памяти, в который Вы можете записать несколько int'ов. Как только Вы, увеличивая k, выйдете за границы этого куска при записи *(tempnum+k)='.'; --- всё, память не Ваша. Писать туда --- непредсказуемый результат.

P.S. Я сам новичок, поэтому могу ошибаться.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 02:04  [ТС]
Возможно, ладно буду думать дальше, а так, если есть еще предложения пишите.
Вообще, если Вы протестируйте, то увидите что с *tempnum = new char[k];
все нормально, так что я думаю, что проблема в другом
0
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 02:16
Я, к сожалению, не могу подебажить Ваш проект --- у меня стоит VS 2010 и при компиляции выкидывает ошибку про отсутствие VS 2008.

Мой совет --- разберитесь, сколько именно элементов должно быть у Вас в массивах и в соответствии с этим сделайте их корректное объявление. При обходе циклов следите, не пишите ли Вы за границы этих массивов.

Добавлено через 6 минут
Цитата Сообщение от CoVeReTeSS Посмотреть сообщение
Возможно, ладно буду думать дальше, а так, если есть еще предложения пишите.
Вообще, если Вы протестируйте, то увидите что с *tempnum = new char[k];
все нормально, так что я думаю, что проблема в другом
Ну, пока k мало, может и нормально. А при бОльших значениях k записывая
C++
1
*(tempnum+k)='.';
рискуете выйти за предел выделенного при
C++
1
char *tempnum = new char[k==0];
блока и записать в чужую память.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 02:18  [ТС]
Вообще *tempnum = new char[k];
ведет себя нормально даже при больших значениях
0
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 02:23
Вот выдержка про минимальный блок:
/* Malloc implementation for multiple threads without lock contention.
Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Wolfram Gloger <wg@malloc.de>
and Doug Lea <dl@cs.oswego.edu>, 2001.
.......
Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead)
8-byte ptrs: 24/32 bytes (including, 4/8 overhead)

When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
needed; 4 (8) for a trailing size field and 8 (16) bytes for
free list pointers. Thus, the minimum allocatable size is
16/24/32 bytes.

Even a request for zero bytes (i.e., malloc(0)) returns a
pointer to something of the minimum allocatable size.
........
Добавлено через 2 минуты
Цитата Сообщение от CoVeReTeSS Посмотреть сообщение
Вообще *tempnum = new char[k];
ведет себя нормально даже при больших значениях
Ну если сделаете
C++
1
*tempnum = new char[0];
, а потом запишите
C++
1
*(tempnum + 1000) = 50
, то даже если это и скомпилируется, это всё равно некорректно.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 02:28  [ТС]
Не это я проверил и по замыслу программы оно не должно выйти за рамки, как и все остальное
0
 Аватар для Enfernuz
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 02:57
Ну как же не выходит за рамки массива, когда Вы пишете
C++
1
2
3
int s=0,k=0,z=0;
char *temp = new char[s];
char *tempnum = new char[k];
, а потом в цикле пишете за границы массива (массив ведь zero-sized):
C++
1
2
3
4
*(temp+s)=*(A+i);
*(tempnum+k)='.';
k++;
s++;
Почитайте ради интереса тему про new type[0]:. Вопрос и первый ответ.

Это не решит сразу Вашу проблему с записью z, но решит проблемы, связанные с тем, что Вы некорректно выделяете память.

Добавлено через 11 минут
А запись в корректно объявленные массивы дебажить куда проще.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 13:10  [ТС]
Мда, посидел немного, а решения все равно не нашел...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.08.2011, 13:10
Помогаю со студенческими работами здесь

Запись в одномерный динамический массив
Доброго времени суток! Записываю в одномерные динамические массивы строки из Excel. Все строки записываются без проблем, а вот при...

Запись в динамический массив с файла
Здравствуйте, выдаёт ошибку при считывания с файла, прошу указать на ошибку в коде. #include&lt;stdio.h&gt; int main(){ int n=30,i; ...

Двумерный динамический массив и запись в него
Всем доброго времени суток.Проблема с записью в двумерный динамический массив Чтение производиться из файла с разделителями. Структура...

Посимвольная запись из консоли в динамический массив
Доброго времени суток! Хочу посимвольно ввести строку из консоли в динамический массив, а в итоге получается какая-то бурда, помогите,...

Считывание ячеек из StringGrid и запись их в динамический массив C++
Доброго времени суток! Совсем недавно начал осваивать Builder C++ и сам синтаксис языка плюсов (до этого изучал Си). Мне необходимо...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru