Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 00:37     Запись значения в динамический массив #1
Добрый вечер,
Сел я на ночь глядя писать программу, но вот проблема
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.
Заранее спасибо!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 00:49     Запись значения в динамический массив #2
*(tempnum3+s+1) -- это Вы уже не в массив пишете.

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

P.S. И не забывайте смещать указатель, а то у вас в цикле s не меняется и получается, что пишете в один и тот же элемент.
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:01  [ТС]     Запись значения в динамический массив #3
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 и все
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:08     Запись значения в динамический массив #4
Если Вы хотите на каждом шаге цикла писать z в последний элемент массива tempnum3, то, да
C++
1
*(tempnum3+s) = z ;
--- то, что нужно.
Остальная логика программы мне не совсем понятна. Например, я раньше нигде не видел подобного синтаксического описания конструкции switch - case
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:10  [ТС]     Запись значения в динамический массив #5
Я просто пишу калькулятор который обрабатывает данные в момент ввода
Это просто кусок Огросного кода с праработанным арифметическим синтаксисом и т.д.


_______________________________________________________________________________

Почему-то проблема осталась и все равно не пишется значение z.
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:23     Запись значения в динамический массив #6
В общем, чисто новичковское имхо:
char *tempnum3 = new char[s+1]; при s = 0 выделяет место под один int. Соответственно, указатель tempnum3+s при s, отличных от нуля, указывает уже не на массив. Валидным будет лишь указатель tempnum3.
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:31  [ТС]     Запись значения в динамический массив #7
То есть как правильно написать?
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:43     Запись значения в динамический массив #8
Ну по сути что происходит: Вы устанавливаете 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 элемент.
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:44  [ТС]     Запись значения в динамический массив #9
Поправил, точнее я и так это сделал, но все равно не идет запись
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:49     Запись значения в динамический массив #10
Вы уверены, что код доходит до этой строчки, а не обрубается на ложности проверок case'ов?
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:51  [ТС]     Запись значения в динамический массив #11
вроде доходит, вот полный код
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, я кое-что тестировал
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 02:01     Запись значения в динамический массив #12
Короче, вся проблема в том, что Вы выделяете некорректное количество памяти.
C++
1
char *tempnum = new char[k==0];
, к примеру, выделит минимальный блок памяти (точный размер не знаю). И это не будет массивом --- неизвестно количество элементов. Просто кусок памяти, в который Вы можете записать несколько int'ов. Как только Вы, увеличивая k, выйдете за границы этого куска при записи *(tempnum+k)='.'; --- всё, память не Ваша. Писать туда --- непредсказуемый результат.

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

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

Добавлено через 6 минут
Цитата Сообщение от CoVeReTeSS Посмотреть сообщение
Возможно, ладно буду думать дальше, а так, если есть еще предложения пишите.
Вообще, если Вы протестируйте, то увидите что с *tempnum = new char[k];
все нормально, так что я думаю, что проблема в другом
Ну, пока k мало, может и нормально. А при бОльших значениях k записывая
C++
1
*(tempnum+k)='.';
рискуете выйти за предел выделенного при
C++
1
char *tempnum = new char[k==0];
блока и записать в чужую память.
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 02:18  [ТС]     Запись значения в динамический массив #15
Вообще *tempnum = new char[k];
ведет себя нормально даже при больших значениях
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 02:23     Запись значения в динамический массив #16
Вот выдержка про минимальный блок:
/* 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
, то даже если это и скомпилируется, это всё равно некорректно.
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 02:28  [ТС]     Запись значения в динамический массив #17
Не это я проверил и по замыслу программы оно не должно выйти за рамки, как и все остальное
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 02:57     Запись значения в динамический массив #18
Ну как же не выходит за рамки массива, когда Вы пишете
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 минут
А запись в корректно объявленные массивы дебажить куда проще.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.08.2011, 13:10     Запись значения в динамический массив
Еще ссылки по теме:

Двумерный динамический массив и запись в него C++
C++ Создать динамический массив, собирающий значения переменной на каждой итерации цикла
C++ Запись структуры данных в файл. Динамический список

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

Или воспользуйтесь поиском по форуму:
CoVeReTeSS
3 / 3 / 0
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 13:10  [ТС]     Запись значения в динамический массив #19
Мда, посидел немного, а решения все равно не нашел...
Yandex
Объявления
18.08.2011, 13:10     Запись значения в динамический массив
Ответ Создать тему
Опции темы

Текущее время: 21:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru