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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
sledge
0 / 0 / 0
Регистрация: 27.07.2009
Сообщений: 13
#1

Вопрос о строках. - C++

12.08.2009, 19:14. Просмотров 1252. Ответов 20
Метки нет (Все метки)

Здравствуйте, все.

Талдычу строки.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <stdio.h>
using namespace std;
 
int main() {
 
    char * pstr1="tes"; 
    short offset=strlen(pstr1)+1;
    
    pstr1="wxyz";
    for(offset*=-1;offset<(short)strlen(pstr1);offset++){
        cout<<"pstr1["<<offset<<"]=="<<*(pstr1+offset)<<endl;
    }
    return 0;
}
вывод
pstr1[-4]==t
pstr1[-3]==e
pstr1[-2]==s
pstr1[-1]==
pstr1[0]==w
pstr1[1]==x
pstr1[2]==y
pstr1[3]==z

Получается, что если присвоить указателю на символ новую строку, то выделятется новый кусок памяти(см. вывод).
Вопрос 1.
Нужно ли заботиться о уплывших байтах? Что-то подсказыватет, что надо.
Вопрос 2.
Если нужно, то подскажите как правильно все сделать.

Спасибо заранее читающим || отвечающим.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.08.2009, 19:14
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Вопрос о строках. (C++):

проясните вопрос в строках - C++
вот программа с объявлениями строк как тип стринг и как массив #include &quot;stdafx.h&quot; #include &quot;iostream&quot; #include &quot;string&quot; ...

Дан целый массив максимальной размерности 20*20. Провести сортировку по возрастанию в нечетных строках массива и по убыванию в четных строках. - C++
Дан целый массив максимальной размерности 20*20. Провести сортировку по возрастанию в нечетных строках массива и по убыванию в четных...

Элементы, расположеные на главной диагонали, в первых 3 строках выше диагонали и в последних 2 строках ниже диагонали переместить в одномерный массив - C++
Нужно элементы расположены на главной диагонали, в первых 3 строках выше диагонали и в последних 2 строках ниже диагонали переместить в...

Вопрос по массивав, "институтский" вопрос. - C++
Готовлюсь к летней сессии по программированию. С++ Есть такая вот задачка (привожу как есть) В документации подобного не...

о строках - C++
вопрос по поводу строк. я хочу в cout выводить русские символы и какие нибудь строки на русском. например string a; ...

Функция в строках - C++
Здравствуйте, помогите пожалуйста с функцией. Где-то что-то я не понимаю по функциям.. Есть строка которая при обработке функцией...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Haster
инженер-системотехник
109 / 108 / 2
Регистрация: 10.03.2009
Сообщений: 533
12.08.2009, 19:33 #2
Что ты понимаешь под уплывающими байтами? Вообще данные строки Являются статическими, т.е. размещаются на этапе компиляции и освобождать память из-под них не нужно. В то же время не факт, что вторую строку он разместит сразу за первой. Так что твои результаты - частный случай...
0
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
12.08.2009, 19:52 #3
Получается, что если присвоить указателю на символ новую строку, то выделятется новый кусок памяти(см. вывод).
Выделяется память из стека,предназначенная для локальных переменных,и все локальные объекты уничтожаются по выходе из блока.(Я полагаю,вызывается деструктор.)
Вопрос 1.
Нужно ли заботиться о уплывших байтах? Что-то подсказыватет, что надо.
Вопрос 2.
Если нужно, то подскажите как правильно все сделать.
В данном случае не нужно.
Но если был использован оператор new,то тогда память нужно освобождать с помощью delete.
C++
1
2
3
4
   char *str = new char;
  ...
   delete [] str;// или
   delete str;
Потому что память выделяется "динамически".То есть программист сам выделяет её из общего доступного пространства и сам должен её освобождать.Я пока сам смутно понимаю данную тему,но вроде так.
0
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
12.08.2009, 20:02 #4
Цитата Сообщение от #pragma Посмотреть сообщение
* *char *str = new char;
* ...
* *delete [] str;// или
* *delete str;
что значит "// или"? в данном случае мы выделяем память используя operator new не для массива, а для одиночного объекта. так что первая форма записи
C++
1
delete [] str
ошибочна
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
12.08.2009, 20:04 #5
А если так?
C++
1
char *str = new char [1]
То есть один элемент не может быть массивом?И потом,при записи
C++
1
char *str=new char;
Выделяется же память под один байт,а если записать туда больше байт?Это ведь тоже будет массив?
0
Gravity
562 / 556 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
12.08.2009, 20:11 #6
#pragma, если записать туда больше одного байта, то можно нарваться на ячейку памяти кем-то уже занятую.
1
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
12.08.2009, 20:14 #7
Но всё таки запись
C++
1
delete []str
корректна,я проверил с компиляцией "gcc -ansi -pedantic -Wall"
0
Rififi
2359 / 1054 / 44
Регистрация: 03.05.2009
Сообщений: 2,656
12.08.2009, 20:46 #8
#pragma,

char *str = new char [1]
То есть один элемент не может быть массивом?И потом,при записи
Это связано с особенностью адресной арифметики с C/C++
Указатель - он всегда указывает на ОДИН элемент (а этот элемент может быть например, массивом). при добавлении числа, машинный адрес изменяется на число * (размер области данных), так что если эта память принадлежит процессу, то мы можем юзать её. так достигается иллюзия работы как с массивом.
1
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,370
12.08.2009, 22:48 #9
Цитата Сообщение от #pragma Посмотреть сообщение
Но всё таки запись [...] корректна,я проверил с компиляцией "gcc -ansi -pedantic -Wall"
Это допустимо с точки зрения компилятора, однако, в соответствии с точным смыслом Стандарта (5.3.5/2), приводит к undefined behavior - неопределенному поведению программы. Если тебе повезет - программа будет работать, как будто ничего не произошло. Если не повезет.... значит, не повезет. В самом неудачном случае невезения будет время от времени появляться невоспроизводимый глюк в программе. И, по закону подлости, он обязательно проявится именно при демонстрации программы Самому Главному Боссу....
1
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
13.08.2009, 00:21 #10
Цитата Сообщение от #pragma Посмотреть сообщение
Выделяется память из стека,предназначенная для локальных переменных,и все локальные объекты уничтожаются по выходе из блока.
в данном случае - нет. и прав Haster: строки находятся в поле констант.

хотите убедиться - посмотрите сюда:

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
void func(){
    DWORD_PTR stackPtr;
    __asm mov [stackPtr], esp;
    cout<<"stack pointer in func: "<<stackPtr<<endl;
    char *pstr1="testestestestestestestestestestestestestestesAAA";
    cout<<"pstr1 in func: "<<pstr1<<endl;
}
 
void func2(){
    DWORD_PTR stackPtr;
    __asm mov [stackPtr], esp;
    cout<<"stack pointer in func2: "<<stackPtr<<endl;
    char *pstr1="111111111111111111111111111111111111111111111111111111222";
    cout<<"pstr1 in func2: "<<pstr1<<endl;
}
 
 
int main(...) {
    DWORD_PTR stackPtr;
    __asm mov [stackPtr], esp;
    cout<<"stack pointer in main before func() call: "<<stackPtr<<endl;
    func();
    __asm mov [stackPtr], esp;
    cout<<"stack pointer in main before func2() call: "<<stackPtr<<endl;
    func2();
    __asm mov [stackPtr], esp;
    cout<<"stack pointer in main after func2() call: "<<stackPtr<<endl;
}
выполните и посмотрите (советую в дибаггере посмотреть что расположено по данным адресам) куда указывает указатель стэка, и где находятся эти строчки. все поймете.

Добавлено через 33 минуты 56 секунд
дополню: указатели
C++
1
char *pstr1
, конечно, будут находиться именно в стэке
0
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,370
13.08.2009, 10:21 #11
Кстати, коллеги, вот простой тест, показывающий разницу между delete и delete[] формами:
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
#include <iostream>
using namespace std;
 
class test
{
public:
    test() { cout << "test ctor" << endl; }
    ~test() { cout << "test dtor" << endl; }
};
 
int main()
{
    test* p = new test[5];
    cout << "----------" << endl;
    delete p;
    //delete[] p;
 
    return 0;
}
 
/*
output:
test ctor
test ctor
test ctor
test ctor
test ctor
----------
test dtor
 
*/
Поскольку это частая ошибка начинающих программистов, мне представляется полезным проиллюстрировать ее.
0
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
13.08.2009, 12:06 #12
теперь проверьте, правильно ли сработают

C++
1
2
    test** p = new test[5][10];
    delete[][] p;
,
C++
1
2
    test*** p = new test[5][10][20];
    delete[][][] p;
...

зачем такие заморочки писать, даже если это "правильно работает"?
0
ISergey
Maniac
Эксперт С++
1374 / 885 / 52
Регистрация: 02.01.2009
Сообщений: 2,658
Записей в блоге: 1
13.08.2009, 12:11 #13
Цитата Сообщение от novi4ok Посмотреть сообщение
теперь проверьте, правильно ли сработают

C++
1
2
    test** p = new test[5][10];
    delete[][] p;
,
C++
1
2
    test*** p = new test[5][10][20];
    delete[][][] p;
Даже не скомпелится..
0
sledge
0 / 0 / 0
Регистрация: 27.07.2009
Сообщений: 13
13.08.2009, 15:41  [ТС] #14
Спасибо за ответы всем. :-) Прочитал и понял как много нужно узнать :-).

Поставлю вопрос, касающийся моего листинга, так:
Переменная pstr1 будет размещена в стеке. Симолы "tes" и "wxyz" будут размещены в стеке или в динамической памяти или еще где-то?

Еще вопрос:
Что за стек пресловутый такой? Читал - про гору тарелок. получается, если в функции main() объявить три переменных(положить 3 тарелки друг на друга), то как мне достать нижнюю переменную? Куда положить две снятые тарелки?

Спасибо за ответы.
0
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
13.08.2009, 17:00 #15
Цитата Сообщение от sledge Посмотреть сообщение
Переменная pstr1 будет размещена в стеке.
правильно.
Цитата Сообщение от sledge Посмотреть сообщение
Симолы "tes" и "wxyz" будут размещены в стеке или в динамической памяти или еще где-то?
"еще где-то". в области констатн. проще выражаясь, они будут являться частью тела вашего скомпилированного модуля.

Цитата Сообщение от sledge Посмотреть сообщение
Еще вопрос:
Что за стек пресловутый такой? Читал - про гору тарелок. получается, если в функции main() объявить три переменных(положить 3 тарелки друг на друга), то как мне достать нижнюю переменную? Куда положить две снятые тарелки?
вам не нужно об этом заботиться вообще, если вы пишете на с++, а не на ассемблере. вы обращаетесь к тарелкам по их именам, а не работаете с указателем стека непосредственно. эти детали берет на себя компилятор.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.08.2009, 17:00
Привет! Вот еще темы с ответами:

Работа в строках - C++
Очень нужна помощь! Ввести строку. Вывести в виде нескольких строк так, чтобы в каждой строке было по 4 слова, первое слово начиналось...

Предложения в строках - C++
Просидел 2 часа и не смог догнать, как реализовать задачу.Решил обратиться к умеющим за помощью. Задача: Написать программу, которая...

Мусор в строках - C++
Привет всем!!! Я пишу помехоустойчивый декодер Витерби. Имеется граф 4x32. struct graf { int rebro0; int rebro1; ...

Поиск в строках - C++
Помогите пожалуйста найти самое короткое слово в предложении из всех слов с длиной не менее 4 символов.


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
13.08.2009, 17:00
Ответ Создать тему
Опции темы

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