powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / sizeof( strcuct {string} )?
25 сообщений из 46, страница 1 из 2
sizeof( strcuct {string} )?
    #39608171
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не, я конечно давно знаю что если хочешь сортировать объекты с переменной длинной, то сортируй указатели на них.
Но.... разве класс string не является сам по себе указателем на данные?
Да даже если оно хранит данные напрямую в структуре и Record.s на самом деле переменной длины, почему тогда значение целого не портится?

Код: plaintext
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.
#include <string>
#include <cstdlib>
#include <array>
#include <iostream>

using namespace std;

struct Record {
	string s;
	int i;
};

int main(int argc, char **argv) {
	array<Record, 5> arr;
	arr[0].s = "qwe";
	arr[1].s = "ertyu";
	arr[2].s = "dfgcvb";
	arr[3].s = "a";
	arr[4].s = "fhuj";

	arr[0].i = 4;
	arr[1].i = 2;
	arr[2].i = 3;
	arr[3].i = 0;
	arr[4].i = 1;

	cout << "original\n";
	for(auto r:arr) cout << r.s << ' ' << r.i << "\n";

	cout << "\nqsort by int\n";
	qsort(arr.begin(), arr.size(), sizeof(Record),
		[](const void* a, const void* b) {
			const Record *ap = static_cast<const Record*>(a);
			const Record *bp = static_cast<const Record*>(b);
			if (ap->i < bp->i) return -1;
			if (ap->i > bp->i) return 1;
			return 0;
		}
	);
	for(auto r:arr) cout << r.s << ' ' << r.i << "\n";

	cout << "\nqsort by string\n";
	qsort(arr.begin(), arr.size(), sizeof(Record),
		[](const void* a, const void* b) {
			const Record *ap = static_cast<const Record*>(a);
			const Record *bp = static_cast<const Record*>(b);
			return ap->s.compare(bp->s);
		}
	);
	for(auto r:arr) cout << r.s << ' ' << r.i << "\n";

	return 0;
}

...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608179
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
При использовании в C++, функция qsort по много раз уничтожает объект (вызывает деструктор у Record и у std::string) и копирует указатель на освобожденную память, поэтому ваш код просто будет падать с Seg Fault.

Потому что для классов из C++ (struct вызывающих деструктор) надо использовать std::sort из C++, а не qsort-из C.
Код: plaintext
1.
2.
3.
4.
5.
6.
	std::sort(arr.begin(), arr.end(),
		[]( Record a,  Record b) -> bool {
			if (a.i < b.i) return true;
			return false;
		}
	);
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608193
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

не подтверждаю.

qsort не знает ничего о сортируемом объекте, С++ не дает такой инфы.

исправленный пример и вывод
Код: plaintext
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.
#include <string>
#include <cstdlib>
#include <array>
#include <iostream>

using namespace std;

struct Record {
	~Record(){ cout << i << "-destructs"<< endl; }
	string s;
	int i;
};

int main(int argc, char **argv) {
	array<Record, 5> arr;
	arr[0].s = "qwe";
	arr[1].s = "ertyu";
	arr[2].s = "dfgcvb";
	arr[3].s = "a";
	arr[4].s = "fhuj";

	arr[0].i = 4;
	arr[1].i = 2;
	arr[2].i = 3;
	arr[3].i = 0;
	arr[4].i = 1;

	cout << "original\n";
	for(const auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	cout << "\nqsort by int\n";
	qsort(arr.begin(), arr.size(), sizeof(Record),
		[](const void* a, const void* b) {
			const Record *ap = static_cast<const Record*>(a);
			const Record *bp = static_cast<const Record*>(b);
			if (ap->i < bp->i) return -1;
			if (ap->i > bp->i) return 1;
			return 0;
		}
	);
	for(const auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	cout << "\nqsort by string\n";
	qsort(arr.begin(), arr.size(), sizeof(Record),
		[](const void* a, const void* b) {
			const Record *ap = static_cast<const Record*>(a);
			const Record *bp = static_cast<const Record*>(b);
			return ap->s.compare(bp->s);
		}
	);
	for(const auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	return 0;
}


zoriginal
qwe 4
ertyu 2
dfgcvb 3
a 0
fhuj 1

qsort by int
a 0
fhuj 1
ertyu 2
dfgcvb 3
qwe 4

qsort by string
a 0
dfgcvb 3
ertyu 2
fhuj 1
qwe 4
4-destructs
1-destructs
2-destructs
3-destructs
0-destructs
gcc 4.9.2

отдыхать надо, среда скоро
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608217
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SiemarglВася Уткин,

не подтверждаю.

qsort не знает ничего о сортируемом объекте, С++ не дает такой инфы.

исправленный пример и вывод
Код: plaintext
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.
#include <string>
#include <cstdlib>
#include <array>
#include <iostream>

using namespace std;

struct Record {
	~Record(){ cout << i << "-destructs"<< endl; }
	string s;
	int i;
};

int main(int argc, char **argv) {
	array<Record, 5> arr;
	arr[0].s = "qwe";
	arr[1].s = "ertyu";
	arr[2].s = "dfgcvb";
	arr[3].s = "a";
	arr[4].s = "fhuj";

	arr[0].i = 4;
	arr[1].i = 2;
	arr[2].i = 3;
	arr[3].i = 0;
	arr[4].i = 1;

	cout << "original\n";
	for(const auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	cout << "\nqsort by int\n";
	qsort(arr.begin(), arr.size(), sizeof(Record),
		[](const void* a, const void* b) {
			const Record *ap = static_cast<const Record*>(a);
			const Record *bp = static_cast<const Record*>(b);
			if (ap->i < bp->i) return -1;
			if (ap->i > bp->i) return 1;
			return 0;
		}
	);
	for(const auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	cout << "\nqsort by string\n";
	qsort(arr.begin(), arr.size(), sizeof(Record),
		[](const void* a, const void* b) {
			const Record *ap = static_cast<const Record*>(a);
			const Record *bp = static_cast<const Record*>(b);
			return ap->s.compare(bp->s);
		}
	);
	for(const auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	return 0;
}


zoriginal
qwe 4
ertyu 2
dfgcvb 3
a 0
fhuj 1

qsort by int
a 0
fhuj 1
ertyu 2
dfgcvb 3
qwe 4

qsort by string
a 0
dfgcvb 3
ertyu 2
fhuj 1
qwe 4
4-destructs
1-destructs
2-destructs
3-destructs
0-destructs
gcc 4.9.2

отдыхать надо, среда скоро
А давно ли чисто сишный qsort() на вход стал принимать итераторы из C++, вместо указателей?

1. Сначала переписывайте с arr.begin() на &arr[0]
2. Затем меняйте static_cast<const Record*>(a); на reinterpret_cast<const Record*>(a);
3. Теперь получайте SegFault и удивляйтесь :)
4. Убирайте временно string s из Record и добавляйте в Record деструктор с выводом сообщения
5. Профит
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608219
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Siemarglgcc 4.9.2

отдыхать надо, среда скорохмммм... У тебя строки не портятся.

Так. Подправлю код чтобы было лучше видно:
Код: plaintext
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.
#include <string>
#include <cstdlib>
#include <array>
#include <iostream>

using namespace std;

struct Record {
	string s;
	int i;
	~Record(){ cout << "-destructs " << s << ' ' << i << "\n"; }
};

int main(int argc, char **argv) {
	array<Record, 5> arr;
	arr[0].s = "red";
	arr[1].s = "green grass";
	arr[2].s = "magenta ball";
	arr[3].s = "black";
	arr[4].s = "gray goose with long neck";

	// uncomment this to fix the output.
	// for(auto &r:arr) r.s.reserve(32);  

	arr[0].i = 4;
	arr[1].i = 2;
	arr[2].i = 3;
	arr[3].i = 0;
	arr[4].i = 1;

	cout << "original\n";
	for(auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	cout << "\nqsort by int\n";
	qsort(arr.begin(), arr.size(), sizeof(Record),
		[](const void* a, const void* b) {
			const Record *ap = static_cast<const Record*>(a);
			const Record *bp = static_cast<const Record*>(b);
			if (ap->i < bp->i) return -1;
			if (ap->i > bp->i) return 1;
			return 0;
		}
	);
	for(auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	cout << "\nqsort by string\n";
	qsort(arr.begin(), arr.size(), sizeof(Record),
		[](const void* a, const void* b) {
			const Record *ap = static_cast<const Record*>(a);
			const Record *bp = static_cast<const Record*>(b);
			return ap->s.compare(bp->s);
		}
	);
	for(auto &r:arr) cout << r.s << ' ' << r.i << "\n";

	return 0;
}


И вывод очень странный:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
original
red 4
green grass 2
magenta ball 3
black 0
gray goose with long neck 1

qsort by int
magen 0
gray goose with long neck 1
▲   m∟@ á∟@ 2
green grass  3
bla 4

qsort by string
▲   m∟@ á∟@ 2
gray goose with long neck 1
magenta ball 3
gre 4
red ♦ 0
-destructs red ♦ 0
-destructs gre 4
-destructs magenta ball 3
-destructs gray goose with long neck 1
-destructs ▲   m∟@ á∟@ 2

Я собираю на 5.3.0 на винде.

А если после создания строк добавить for(auto &r:arr) r.s.reserve(32); (оно там закоментировано сейчас). То все становится замечательно.
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608224
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Начиная с GCC 5.1.0 уже падает с ошибкой памяти: https://wandbox.org/permlink/SDDOPMgBqGjgLfT7

На clang везде где компилируется с 3.5.0 по Head 7.0 - работает нормально: https://wandbox.org/permlink/qNn1lnocaiHEab4W

Ну и на винде судя по всему работает, но неправильно - портит символы. Вот они грязные хаки к чему приводят )
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608232
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася регайся. Чорт тебя подери
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608233
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

нет там грязных хаков.

надо брвть норм версию компилятора, а не говнобету 5.1, и разбираться
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608241
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
maytonВася регайся. Чорт тебя подери
Пока без багов писать не начнёте не зарегюсь
SiemarglВася Уткин,

нет там грязных хаков.

надо брвть норм версию компилятора, а не говнобету 5.1, и разбираться
Siemargl
Код: plaintext
1.
2.
3.
array<Record, 5> arr;
//...
	qsort(arr.begin(), arr.size(), sizeof(Record), 


Вопрос, что надо передать в qsort: результат функции begin() или data()?
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf Page 480
21.2.2 Header <cstdlib> synopsis
// 28.8, C standard library algorithms
void qsort( void* base, size_t nmemb, size_t size, c-compare-pred * compar);
void qsort( void* base, size_t nmemb, size_t size, compare-pred * compar);
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf Page 1049
28.8 C library algorithms
void qsort( void* base, size_t nmemb, size_t size, c-compare-pred * compar);
void qsort( void* base, size_t nmemb, size_t size, compare-pred * compar);
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf Page 872
26.3.7.1 Class template array overview
// iterators:
constexpr iterator begin() noexcept;
constexpr const_iterator begin() const noexcept;
constexpr iterator end() noexcept;
constexpr const_iterator end() const noexcept;

constexpr T * data() noexcept;
constexpr const T * data() const noexcept;
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608485
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White OwlА если после создания строк добавить for(auto &r:arr) r.s.reserve(32); (оно там закоментировано сейчас). То все становится замечательно.
Очевидно же, что это все из-за small string optimization в std::string начиная с gcc 5.1, т.к. сишный qsort() использует memcpy() вместо operator=() и конструктора.
В общем грязные хаки такие как передавать итератор вместо указателя или использовать сишный qsort() для классов с конструкторами и операторами копирования ни к чему хорошему не приводят.

https://isocpp.org/blog/2015/04/gcc-5.1-released GCC 5.1 released
A new implementation of std::string is enabled by default, using the small string optimization
instead of copy-on-write reference counting.

Что будет если запустить такой код? https://wandbox.org/permlink/9pfxYTio5N2mK6yH
Код: plaintext
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.
#include <string>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <array>
#include <iostream>

struct small_str_opt {
 char buff[16];
 char *ptr;
 size_t length;
 small_str_opt() : length(0), ptr(buff) {}
 small_str_opt(char const* src) {
  length = strlen(src);
  if(length<= 16) ptr = buff;
  else ptr = (char *)malloc(length); 
  memcpy(ptr, src, length);
 }
 small_str_opt operator=(small_str_opt const& src) {
   if(src.length > length) {
    if(length > 16) free(ptr);
    if(src.length > 16) ptr = (char *)malloc(src.length);
   }
   length = src.length;
   memcpy(ptr, src.ptr, length);
 }
  ~small_str_opt() { if(length > 16) free(ptr); }
};

std::ostream& operator<< (std::ostream& out, small_str_opt const val) {
  for(size_t i = 0; i < val.length; ++i) out << val.ptr[i];
  return out;
}

int main() {
 small_str_opt s1 = "qwert", s2 = "ab", s_tmp;
 std::cout << "In: s1 = " << s1 << ", s2 = " << s2 << std::endl;
    
/*
 // std::sort
 s_tmp = s1;
 s1 = s2;
 s2 = s_tmp;
 std::cout << "op=(): s1 = " << s1 << ", s2 = " << s2 << std::endl;
*/   
    
 // qsort()
 memcpy(&s_tmp, &s1, sizeof(small_str_opt));
 memcpy(&s1, &s2, sizeof(small_str_opt));
 memcpy(&s2, &s_tmp, sizeof(small_str_opt));
    
 // damaged strings
 std::cout << "Out: s1 = " << s1 << ", s2 = " << s2 << std::endl;

 return 0;
}
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608495
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася Уткин,

плохо. падает прозрачность языка

в целом это негативно сказывается на производительности

да и на понимаемости. см топик и 21223495 =)
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608497
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemarglв целом это негативно сказывается на производительности
А можно по конкретней, как small string optimization плохо сказывается на производительности?
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608620
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинSiemarglв целом это негативно сказывается на производительности
А можно по конкретней, как small string optimization плохо сказывается на производительности?
вот же и пример - сортировать "в лоб" нельзя, копирование будет медленнее (особенно массивов строк)

но я имел в виду больше - сокрытие деталей "под капотом" мешает пониманию - что же на самом деле происходит, ну и конечно как писать оптимальный код, если непонятны накладные расходы
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608696
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SiemarglВася Уткинпропущено...

А можно по конкретней, как small string optimization плохо сказывается на производительности?
вот же и пример - сортировать "в лоб" нельзя, копирование будет медленнее (особенно массивов строк)

но я имел в виду больше - сокрытие деталей "под капотом" мешает пониманию - что же на самом деле происходит, ну и конечно как писать оптимальный код, если непонятны накладные расходы
Насчет понимания кода под копотом - согласен. Я понимал, что дело в memcpy() вместо operator=(), т.е. qsort не предназначен для C++-struct/class, но сначала подумал на деструктор временной переменной используемой для обмена местами двух элементов, а присмотревшись понял, что дело в small string optimization, а не в деструкторе.

А почему сортировка будет медленней? На GCC 4.9.2 (без smo) std::string занимает 8 байт, а на GCC 5.1.0 (с smo) std::string занимает 32 байта. Но CPU читает данные из памяти сразу кэш-линиями по 64 байта:
- В gcc 4.9.2 всегда надо прочитать как минимум 2 кэш-линии и автоматический префетч кэша не поможет, т.к. каждый динамически аллоцируемый участок не расположен строго один за другим.
- А в gcc 5.1.0 во многих случаях достаточно прочитать 1 кэш линию и плюс автоматический префетч загрузит все ближайшие элементы массива в кэш, т.к. они расположены последовательно.

И ладно, допустим, что smo - это шляпа. Но правильно ли использовать qsort() для C++-struct/class?
Самое главное - в каждой конкретной задаче разработчик может захотеть сделать свои оптимизации в конструкторе и operator(), которые в его задаче точно нужны, и использование qsort() сломает код, а std::sort() не сломает.
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608698
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинВопрос, что надо передать в qsort: результат функции begin() или data()? С совсем формальной точки зрения - array<>::data().
Но учитывая что речь идет про array<>, а его итерторы это простые указатели. Так что в данном конкретном случае begin() и data() фактически одно и то-же.
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608711
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Читал топик, ломал голову что могло сглючить из-за memcpy()

Придумал один вариант и он подтвердился
Вася Уткин
Код: plaintext
1.
2.
3.
4.
5.
struct small_str_opt {
 char buff[16];
 char *ptr;
...
  if(length<= 16) ptr = buff;
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608789
Вася Уткин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White OwlВася УткинВопрос, что надо передать в qsort: результат функции begin() или data()? С совсем формальной точки зрения - array<>::data().
Но учитывая что речь идет про array<>, а его итерторы это простые указатели. Так что в данном конкретном случае begin() и data() фактически одно и то-же.
Фактически это: auto it = arr.begin(); Record *ptr = *reinterpret_cast<Record **>(&it);
Пока что да - указатель, но когда то и std::string был просто указателем на данные )
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608843
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вася УткинПри использовании в C++, функция qsort по много раз уничтожает объект (вызывает деструктор у Record и у std::string) и копирует указатель на освобожденную память, поэтому ваш код просто будет падать с Seg Fault.

Потому что для классов из C++ (struct вызывающих деструктор) надо использовать std::sort из C++, а не qsort-из C.
Код: plaintext
1.
2.
3.
4.
5.
6.
	std::sort(arr.begin(), arr.end(),
		[]( Record a,  Record b) -> bool {
			if (a.i < b.i) return true;
			return false;
		}
	);



Ничего не должно тут падать.
Но падает.
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39608844
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl,

А вот нафига же тебе там void* ?
Когда ну всё уже сделано в С++ чтобы все указатели были типизированы.
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39609356
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivWhite Owl,

А вот нафига же тебе там void* ?
Когда ну всё уже сделано в С++ чтобы все указатели были типизированы.Мне??? Это вообще-то требование библиотечной функции std::qsort() .
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39609414
д0kХ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TЧитал топик, ломал голову что могло сглючить из-за memcpy()

Придумал один вариант и он подтвердился
Вася Уткин
Код: plaintext
1.
2.
3.
4.
5.
struct small_str_opt {
 char buff[16];
 char *ptr;
...
  if(length<= 16) ptr = buff;



Я когда то очень давно в эпоху беззаботной юности
и большого количества свободного времени ,
игрался в велосипедостроение на эту тему,
что бы съкономить на вызовах выделения памяти для коротких строк.

Там должен быть union в типизационной обертке
char* operator()
или
const char* operator()

если нужно передавать в функцию требующую void*
то конечно же тип нужно явыным образом привести под
неявный вызов operator().
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39611559
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlНе, я конечно давно знаю что если хочешь сортировать объекты с переменной длинной, то сортируй указатели на них.
Но.... разве класс string не является сам по себе указателем на данные?
Да даже если оно хранит данные напрямую в структуре и Record.s на самом деле переменной длины, почему тогда значение целого не портится?


Пару раз прочитал, не очень понятно. Почему при сортировке с использованием стандартных функций С и С++ мы можем ожидать в качестве побочного эффекта изменение сортируемых объектов?
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39611563
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryWhite OwlНе, я конечно давно знаю что если хочешь сортировать объекты с переменной длинной, то сортируй указатели на них.
Но.... разве класс string не является сам по себе указателем на данные?
Да даже если оно хранит данные напрямую в структуре и Record.s на самом деле переменной длины, почему тогда значение целого не портится?


Пару раз прочитал, не очень понятно. Почему при сортировке с использованием стандартных функций С и С++ мы можем ожидать в качестве побочного эффекта изменение сортируемых объектов?
Ах да, надо бы разъяснить.

Строка переместилась, но она содержала указатель на себя, который остался указывать на старое место.
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39611611
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryWhite OwlНе, я конечно давно знаю что если хочешь сортировать объекты с переменной длинной, то сортируй указатели на них.
Но.... разве класс string не является сам по себе указателем на данные?
Да даже если оно хранит данные напрямую в структуре и Record.s на самом деле переменной длины, почему тогда значение целого не портится?


Пару раз прочитал, не очень понятно. Почему при сортировке с использованием стандартных функций С и С++ мы можем ожидать в качестве побочного эффекта изменение сортируемых объектов?

Так написано же:
Код: plaintext
  "The type of the elements of the array must be a  TrivialType , otherwise the behavior is undefined."
...
Рейтинг: 0 / 0
sizeof( strcuct {string} )?
    #39611623
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПару раз прочитал, не очень понятно. Почему при сортировке с использованием стандартных функций С и С++ мы можем ожидать в качестве побочного эффекта изменение сортируемых объектов?
Наоборот: объекты не меняются, но должны, т.к. внутри string буфер и указатель на этот буфер.
Выше пример кода который сглючит 21224926 и 21226275
...
Рейтинг: 0 / 0
25 сообщений из 46, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / sizeof( strcuct {string} )?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]