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

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

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

Author24 — интернет-сервис помощи студентам
Добрый вечер,
Сел я на ночь глядя писать программу, но вот проблема
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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.08.2011, 00:37
Ответы с готовыми решениями:

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

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

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

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

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


_______________________________________________________________________________

Почему-то проблема осталась и все равно не пишется значение z.
0
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:23 6
В общем, чисто новичковское имхо:
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  [ТС] 7
То есть как правильно написать?
0
22 / 22 / 2
Регистрация: 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 элемент.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 01:44  [ТС] 9
Поправил, точнее я и так это сделал, но все равно не идет запись
0
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 01:49 10
Вы уверены, что код доходит до этой строчки, а не обрубается на ложности проверок case'ов?
0
3 / 3 / 3
Регистрация: 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, я кое-что тестировал
0
22 / 22 / 2
Регистрация: 11.04.2011
Сообщений: 67
18.08.2011, 02:01 12
Короче, вся проблема в том, что Вы выделяете некорректное количество памяти.
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  [ТС] 13
Возможно, ладно буду думать дальше, а так, если есть еще предложения пишите.
Вообще, если Вы протестируйте, то увидите что с *tempnum = new char[k];
все нормально, так что я думаю, что проблема в другом
0
22 / 22 / 2
Регистрация: 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];
блока и записать в чужую память.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 02:18  [ТС] 15
Вообще *tempnum = new char[k];
ведет себя нормально даже при больших значениях
0
22 / 22 / 2
Регистрация: 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
, то даже если это и скомпилируется, это всё равно некорректно.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 02:28  [ТС] 17
Не это я проверил и по замыслу программы оно не должно выйти за рамки, как и все остальное
0
22 / 22 / 2
Регистрация: 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 минут
А запись в корректно объявленные массивы дебажить куда проще.
0
3 / 3 / 3
Регистрация: 24.03.2011
Сообщений: 99
18.08.2011, 13:10  [ТС] 19
Мда, посидел немного, а решения все равно не нашел...
0
18.08.2011, 13:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.08.2011, 13:10
Помогаю со студенческими работами здесь

Запись в динамический массив с файла
Здравствуйте, выдаёт ошибку при считывания с файла, прошу указать на ошибку в коде....

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

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

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


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru