-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCpp_Tips_Tricks.txt
executable file
·7328 lines (5648 loc) · 318 KB
/
Cpp_Tips_Tricks.txt
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
0 What are Classes
1. Using namespace std;
2. How to split a string
3. Use of cin ignore
4. Why to use nested class
5. NULL pointer - nullptr
6. Print contents of a vector:
7. Convert string to Upper Case / Lower case:
7b. Converting a single character to upper / lower case
8. Switch can't be used on strings:
9. Copy String to Char array
10. Char * vs Char []
11. Char * assignment
12. Passing Array requires number of elements. Arrays decay into pointers.
13. Deleting Array of objects using delete[]. delete[] vs delete
13b. What happens on delete
13c. Is there delete in Java
14. Setting pointers to NULL after delete
15. cout << new int[0] << endl; Allocating new with size 0
16. Default value of a boolean in a struct
17. Clearing a Char array in C
18. Re-declaration of default parameter
19. IMP: Char array vs NULL terminated String
C FAQs
19b. Why should SCANF never be used
19c. But I heard that char a[] was identical to char *a.
20a. Compare / Comparing String in C++
20b. Find Substring
21. Combining vector of strings:
22. Convert String to Int - C++
22a. Concatenate String with Int
22b. Convert INT to STRING
23. Align std out
24. IMP: Why Pointer207.62 / 6s
25. Garbage Collection:
26. C++ Pointer vs References:
26b. When to use References vs. Pointers
27. Smart Pointer:
28. C++ Cast:
28b. Static Cast vs Reinterpret Cast
28c. Static Cast vs Dynamic Cast
29. C++ to Java:
30. Finding all subsets of a Vector of Vector
31. double vs float
32. C++ Count occurrences of a char
33. C++ Cin:
34. C++ Empty String:
35. Stack Unwinding
36. RAII:
37. Branch Prediction:
38. Monitors in C++
39. PThreads:
40. Convert Vector to Array and Array to Vector
41. Initialization of a normal array with one default value
42. Templates: Template keyword vs Class keyword
43. comparing int with size_t
44. Unicode vs Ascii
45. Where are Class Members stored in memory
45b. Memory Layout - Code Segment Data Segment Stack Heap
45c. ELF and how it is used for compiling and linking
How are the different segments like heap, stack, text related to the physical memory
45d. What is a Symbol Table
46. C++ Class vs C Struct Memory Layout
47. Pass by Value vs Const Reference
47b. Why is Pass by Value faster than Pass by reference
48. Virtual Function and Pure Virtual Functions
49. Virtual Functions
49b. How Virtual Functions Work
50. new vs new()
51. Reading Multiple words from cin
52. Reading multiple lines from cin
53. Using size_t for loops. Why use size_t instead of unsigned int or unsigned long
54. size_t vs size_type
55. File IO
57. Meaning of const
57a. Const vs ReadOnly
57b. Const in C vs C++
58. Reason to pass a pointer by reference
59. Returning by reference:
60. Sorting a vector of objects
61. Find rightmost set bit
61b. Find leftmost set bit
62. #define vs typedef vs Enum vs Static Const
62a. C++ Const vs #Define
62a. C++ semantics of `static const` vs `const`
62b. C++ Const Read Only
62b. Const defaults to Internal Linkage in C++ and External Linkage in C
62c. When to use unnamed namespace
62d. Superiority of unnamed namespace over static
63. Dynamic Array in C++
63b. TWOD Vector in C++
64. Time in C++
65. Ordered Data Set
66. Tail Recursion
67. Extern Variable; Static vs Extern
68. vector<bool> vs bitset
69. Reading from file, donot use EOF for checking
70. Struct assignment vs memcpy
71. Why 2's complement is used to represent negative numbers
72. Extern Linkage and Intern linkage and NO linkage
73. How a Computer Compiles and Executes a C++ Program
74. When / Why to use stringstream
75. Steps involved for execution of a C program
75a. Storage Classes - Static, Extern, Auto and Register
76. Abstract Class vs Interface
77. Can abstract class be instantiated
78. C++ new int[0] - will it allocate memory
79. C++ new vs C malloc
80. How is memory allocated to Vectors
80b. Vector Resize vs Reserve
81. Where Global Variables and Pointers are stored
82. Where are the Variable Names stored in memory
82b. Where in memory are return values stored in memory
83. What is Type Safe
84. What is the name of the --> operator
85. Why is ::operator new[] necessary when ::operator new is enough
86. Allocator vs New
87. What is RTTI and Why is it necessary
88. When to use static methods
89. Freeing memory twice
90. C++ Memory management New operator vs Operator new
91. STACK VS HEAP
92. Different behavior of Code Valid in C and C++
93. Case Only Labels: Jumping over initialization
94. What uses are there for placement new?
95. Is there a "placement delete"?
96a. What is a smart pointer and when should I use one
96b. Auto, Unique, Shared Pointers, Weak Pointers and Scoped Pointers
96c. When is std::weak_ptr useful
96c. Scoped Pointer vs Unique Pointer
97. Vector - Accessing member elements using "at()" vs "[]"
98. Create Vectors of User defined size
99. How to use memset or fill_n to initialize a dynamic two dimensional TwoD array in C++
99a. How to fill a Dynamic 1D Array to all 0s
100. Unique Lock unique_lock
100a. How to use unique_lock
101a. Nice Threading tutorial
101. Condition Variable
102. Lock guard vs Unique lock Lock_guard vs Unique_lock
103. Recursive Mutex
104. Lock vs Mutex vs Condition Variable
105. Need for THIS Pointer
106. Sort Unordered Map
106b. Sort Unordered Map by values
106c. Sort vector of pairs
107. IMP: Using [] operator in unordered_map inserts the element if not present.
107b. Single line increment or set zero for unordered_map
108. Create a vector of userdefined size and initialize with default values
108b. Create a vector with an element using constructor
109. Copy from one vector to another
110. Copy Constructor vs Assignment Operator:
110b. Private Copy Constructor and Assignment Operator - Singleton Class
111. Volatile keyword:
112. How do you declare an interface in C++
113. Multiple Inheritence in C++
114. Exception handling in C++
115. Side effects of macros:
116. Macros vs Inline Function:
117. What is Arithmetic Overflow and Underflow
118. How to detect integer overflow in C/C++
119. Usage of Templates Function and Class
120. Passing a 2D array to a C++ function
121. Custom Comparator for Priority Queue
122. C++ Erase vector element by value rather than by position
122b. Erase Vector element by position
122c. Delete or Erase or Clear a complete vector
123. Function Pointers and Callbacks
123b. How do function pointers in C work
124. Registering a Callback
125. Functors in C++
126. Operator Overloading in C++
127. Scope Guard in C++
128. C++11 introduced a standardized memory model. What does it mean?
129a. Void* Pointer vs NULL Pointer
129. When is void* useful
130. Virtual Destructor in C++
130b. Virtual Constructor in C++
131. Print Unordered Map. Get key and get value
132. Self Referential Structures
133. How to use std::sort to sort a vector
134. Queue vs Vector
135. Differences between various Custom Comparator functions in C++
136. Creating a Vector and bitset on heap
137. Custom Hash Function
138. Fastest way to reset every value of std::vector<int> to 0
139. Using find_first_not_of and find_first_of
140. Best way to extract a subvector from a vector?
141. Running GDB on mac
142. C++ enable/disable debug messages of std::couts on the fly
143. Why use apparently meaningless do-while and if-else statements in C/C++ macros
144. Printing lists with commas such that no ending comma C++
145. Nested Class Access Specifiers
146. Forward Declarations
147. Access Specifier: Public, Private, Protected. Class Visiblity Difference during inheritance
148. What is std::move
149. Why is sizeof empty class 1
150. Use of std::endl vs \n
151. Bitset to convert Integer to String Bits and String Bits to Int
152. Print binary of a number using bitset
153. Using iter_swap to swap elements in a vector
154. strcmp vs strncmp vs memcmp vs bcmp
155. bcmp, bzero, bcopy
156. Why constant first in a IF statement and then an expression
157. Convert char * to std::string
158. How to call a C function or a header from a C++ file - extern C
159. #if 0
160. Fastest way to check if a number is even or odd
161a. Multithreading in General
161b. Multithreading - Calling a Class's member function from main thread using objects
162. Creating vector of threads
163. What is std::atomic
164. Inserting at random position to vector - Not possible
165. Print entire contents of a char arry in c++
166. What is the use of explicit keyword
167. What does new() return on failure
168. Pass by reference to a class constructor
169. Porting C code to C++ and C++ code to C - Things to keep in mind
170. Write Pointer to a Function that takes an int array of pointers
171. cout cerr and clog
172. Big Endian vs Little Endian
173. Append Char to String
174. Remove / Erase character from string
175. Passing unordered_map as const is not possible
176. Is it better to return Object or Pass by Reference - Return Value Optimization
177. INT_MIN, INT_MAX numeric_limits
178. binary_search a vector
179. Difference between declaring variables before or in loop
180. Are bitwise operations faster. If so Why
181. Left Shift and Right Shift on Negative numbers
182. Arithmetic Shift vs Logical Shift Operators
183. Are C++ String mutable when passed to function
184. Convert Vector to String
185. Convert INT array to String
186. How to reverse a C++ vector
187. Use of functional's std::function
188. C vs C++
189. Overloading by const
190. Overloading does not work with inheritence
191. Delete this
192. Cannot push unique_ptr to vector
193. Reverse a C++ string
194. Turn off structure padding
195. Lambda functions
196. Concurrency in C++ (Future, promise, .then())
197. Sort a vector of vector and delete duplicates
198. Default Constructor
199. Difference between string.h and cstring?
200. Sleep in C and C++
201. Remove range of elements from vector
202. C++ Data Structures
203. What are inclusion guards
204. Modulo of negative numbers
205. How to dynamically allocate a Two 2D array in C
205a. Free Array of Pointers
205b. How to dynamically allocate a Two 2D array in C++
206. Does std::string contain null terminator?
207. Read file line by line in C
208. Read Write file line by line in C++
------------------------------------------------------------------------------------------
0.
What are Classes
Classes are a collection of functions which operate on data.
1.
Using namespace std;
http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
Say you have,
using namespace foo; has function foos()
using namespace bar; has function bars()
In version 2.0, foo comes up with a function bars(). Then we will end up calling the other function.
So use foo::foos(), bar::bars()
2.
How to split a string
http://stackoverflow.com/questions/236129/split-a-string-in-c
#include <string>
#include <sstream>
#include <vector>
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim)
{
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
void splitStringByPatternString(const string& s, const string& pattern, vector<string>& words)
{
int startIndex = 0;
unordered_set<char> patternSet;
for (char c : pattern)
{
patternSet.insert(c);
}
for(int i = 0; i < s.length(); i++)
{
// If the character is present in the pattern, the split the word
if (patternSet.find(s[i]) != patternSet.end())
{
if (startIndex != i)
{
words.push_back(s.substr(startIndex, i - startIndex));
startIndex = i + 1;
}
else
{
++startIndex;
}
}
}
}
void splitStringIntoWords(const string& s, vector<string>& words)
{
int startIndex = 0;
for(int i = 0; i < s.length(); i++)
{
if (s[i] == ' ' || ispunct(s[i]))
{
if (startIndex != i)
{
words.push_back(s.substr(startIndex, i - startIndex));
startIndex = i + 1;
}
else
{
++startIndex;
}
}
}
}
C++ Find Substring using a pattern
http://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c
Parsing with a single char delimiter is fine. But what if I want to use a string as delimiter.
Example: I want to split:
scott>=tiger
with >= as delimiter so that I can get scott and tiger.
You can use the std::string::find() function to find the position of your string delimiter, then use std::string::substr() to get a token.
Example:
std::string s = "scott>=tiger";
std::string delimiter = ">=";
std::string token = s.substr(0, s.find(delimiter)); // token is "scott"
The find(const string& str, size_t pos = 0) function returns the position of the first occurrence of str in the string, or npos if the string is not found.
The substr(size_t pos = 0, size_t n = npos) function returns a substring of the object, starting at position pos and of length npos
3.
Use of cin ignore
http://stackoverflow.com/questions/25475384/when-and-why-do-i-need-to-use-cin-ignore-in-c
http://stackoverflow.com/questions/5131647/why-would-we-call-cin-clear-and-cin-ignore-after-reading-input
Essentially, for std::cin statements you use ignore before you do a getline call, because when a user inputs something with std::cin, they hit enter and a '\n' char gets into the cin buffer.
Then if you use getline, it gets the newline char instead of the string you want.
So you do a std::cin.ignore(1000,'\n') and that should clear the buffer up to the string that you want.
cin.ignore(256, '\n');
// cin returns false if an input operation fails, that is, if
// something other than an int (the type of input_var) is entered.
while (!(cin >> input_var)) {
cout << "Please enter numbers only." << endl;
cin.clear(); // Both lines are very important
cin.ignore(10000,'\n');
}
The cin.clear() clears the error flag on cin (so that future I/O operations will work correctly), and then
cin.ignore(10000, '\n') skips to the next newline (to ignore anything else on the same line as the non-number so that it does not cause another parse failure).
It will only skip up to 10000 characters, so the code is assuming the user will not put in a very long, invalid line.
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::ws
Discards leading whitespace from an input stream.
std::istringstream s(" this is a test");
std::string line;
getline(s >> std::ws, line);
std::cout << "ws + getline returns: \"" << line << "\"\n";
4.
Why to use nested class
http://stackoverflow.com/questions/4571355/why-would-one-use-nested-classes-in-c
Cool to hide implementation details:
class List
{
public:
List(): head(NULL), tail(NULL) {}
private:
class Node
{
public:
int data;
Node* next;
Node* prev;
};
private:
Node* head;
Node* tail;
};
5.
NULL pointer - nullptr
http://stackoverflow.com/questions/1282295/what-exactly-is-nullptr
http://stackoverflow.com/questions/20509734/null-vs-nullptr-why-was-it-replaced?lq=1
nullptr is always a pointer type. 0 (aka. C's NULL bridged over into C++) could cause ambiguity in overloaded function resolution, among other things:
f(int);
f(foo *);
void printA1(int ptr)
{ }
// The below line throws a warning
// NullPtr.cpp:19:17: warning: passing NULL to non-pointer argument 1 of 'void printA1(int)' [-Wconversion-null]
printA1(NULL);
// The below line throws an error
// NullPtr.cpp:22:20: error: cannot convert 'std::nullptr_t' to 'int' for argument '1' to 'void printA1(int)'
printA1(nullptr);
6.
Print contents of a vector:
http://stackoverflow.com/questions/10750057/c-printing-out-the-contents-of-a-vector
Solution 1:
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Solution 2:
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
7.
Convert string to Upper Case:
http://stackoverflow.com/questions/735204/convert-a-string-in-c-to-upper-case
http://www.cplusplus.com/reference/algorithm/transform/
#include <algorithm>
#include <string>
std::string str = "Hello World";
std::transform(str.begin(), str.end(),str.begin(), ::toupper);
unary operation(1)
template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperation op);
binary operation(2)
template <class InputIterator1, class InputIterator2,
class OutputIterator, class BinaryOperation>
OutputIterator transform (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result,
BinaryOperation binary_op);
#include <functional> // std::plus
int op_increase (int i) { return ++i; }
std::vector<int> foo; // foo: 10 20 30 40 50
std::vector<int> bar;
std::transform (foo.begin(), foo.end(), bar.begin(), op_increase);
// bar: 11 21 31 41 51
// std::plus adds together its two arguments:
std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
// foo: 21 41 61 81 101
7b. Converting a single character to upper / lower case
There are two different tolower functions. The one that you're using is this one, which returns an int. That's why it's printing 116. That's the ASCII value of 't'
std::cout << std::tolower('T', std::locale()); // prints t
8.
Switch can't be used on strings:
http://stackoverflow.com/questions/650162/why-switch-statement-cannot-be-applied-on-strings
The reason why has to do with the type system. C/C++ doesn't really support strings as a type.
It does support the idea of a constant char array but it doesn't really fully understand the notion of a string.
9.
Copy String to Char array
http://stackoverflow.com/questions/13294067/how-to-convert-string-to-char-array-in-c
string tmp = "cat";
char tab2[1024];
strcpy(tab2, tmp.c_str());
For safety, you might prefer:
string tmp = "cat";
char tab2[1024];
strncpy(tab2, tmp.c_str(), sizeof(tab2));
tab2[sizeof(tab2) - 1] = 0;
10.
Char * vs Char []
http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c
https://www.geeksforgeeks.org/whats-difference-between-char-s-and-char-s-in-c/
char *s = "Hello world";
will place Hello world in the read-only parts of the memory and making s a pointer to that, making any writing operation on this memory illegal. While doing:
char s[] = "Hello world";
puts the literal string in read-only memory and copies the string to newly allocated memory on the stack. Thus making
s[0] = 'J';
legal.
First off, in function arguments, they are exactly equivalent:
void foo(char *x);
void foo(char x[]); // exactly the same in all respects (note! this only applies if the brackets are empty)
In other contexts, char * allocates a pointer, while char [] allocates an array. Where does the string go in the former case, you ask? The compiler secretly allocates a static anonymous array to hold the string literal. So:
char *x = "Foo";
// is approximately equivalent to:
static const char __secret_anonymous_array[] = "Foo";
char *x = (char *) __secret_anonymous_array;
Note that you must not ever attempt to modify the contents of this anonymous array via this pointer; the effects are undefined (often meaning a crash):
x[1] = 'O'; // BAD. DON'T DO THIS.
Using the array syntax directly allocates it into new memory. Thus modification is safe:
char x[] = "Foo";
x[1] = 'O'; // No problem.
However the array only lives as long as its contaning scope, so if you do this in a function, don't return or leak a pointer to this array - make a copy instead with strdup() or similar. If the array is allocated in global scope, of course, no problem.
char s[] = "hello";
Creates one object - a char array of size 6, called s, initialised with the values 'h', 'e', 'l', 'l', 'o', '\0'.
Where this array is allocated in memory, and how long it lives for, depends on where the declaration appears.
If the declaration is within a function, it will live until the end of the block that it is declared in, and almost certainly be allocated on the stack; if it's outside a function, it will probably be stored within an "initialised data segment" that is loaded from the executable file into writeable memory when the program is run.
On the other hand, this declaration:
char *s ="hello";
Creates two objects:
a read-only array of 6 chars containing the values 'h', 'e', 'l', 'l', 'o', '\0', which has no name and has static storage duration (meaning that it lives for the entire life of the program); and
a variable of type pointer-to-char, called s, which is initialised with the location of the first character in that unnamed, read-only array.
The unnamed read-only array is typically located in the "text" segment of the program, which means it is loaded from disk into read-only memory, along with the code itself.
The location of the s pointer variable in memory depends on where the declaration appears (just like in the first example)
11.
Char * assignment
http://stackoverflow.com/questions/20944784/why-is-conversion-from-string-constant-to-char-valid-in-c-but-invalid-in-c
char* p = "abc"; // valid in C, invalid in C++
It uses a deprecated implicit conversion--a string literal should be treated as being of type char const *, since you can't modify its contents
12.
Passing Array requires number of elements. Arrays decay into pointers.
http://stackoverflow.com/questions/2559896/how-are-arrays-passed
They are passed as pointers. This means that all information about the array size is lost.
13.
Deleting Array of objects using delete[]. delete[] vs delete
http://stackoverflow.com/questions/703691/how-does-delete-know-its-an-array
http://stackoverflow.com/questions/197675/how-does-delete-know-the-size-of-the-operand-array?lq=1
The compiler doesn't know it's an array, it's trusting the programmer. Deleting a pointer to a single int with delete [] would result in undefined behavior.
Foo* set = new Foo[100];
// ...
delete [] set;
When you allocate memory on the heap, your allocator will keep track of how much memory you have allocated.
This is usually stored in a "head" segment just before the memory that you get allocated.
That way when it's time to free the memory, the de-allocator knows exactly how much memory to free.
If the runtime libraries (not the OS, really) can keep track of the number of things in the array, then why do we need the delete[] syntax at all? Why can't a single delete form be used to handle all deletes?
The answer to this goes back to C++'s roots as a C-compatible language (which it no longer really strives to be.)
Stroustrup's philosophy was that the programmer should not have to pay for any features that they aren't using.
If they're not using arrays, then they should not have to carry the cost of object arrays for every allocated chunk of memory.
That is, if your code simply does
Foo* foo = new Foo;
then the memory space that's allocated for foo shouldn't include any extra overhead that would be needed to support arrays of Foo.
Since only array allocations are set up to carry the extra array size information, you then need to tell the runtime libraries to look for that information when you delete the objects.
That's why we need to use
delete[] bar;
instead of just
delete bar;
if bar is a pointer to an array.
13b.
What happens on delete
http://stackoverflow.com/questions/11603005/what-does-delete-command-really-do-for-memory-for-pointers-in-c
Think of memory as a big warehouse with lots of boxes to put things into.
When you call "new", the warehouse staff finds an unused box large enough for your needs, records that box as being owned by you (so it's not given to someone else), and gives you the number of that box so you can put your stuff into it.
This number would be the "pointer".
Now, when you "delete" that pointer, the reverse happens: the warehouse staff notes that this particular box is available again.
Contrary to real warehouse staff they aren't doing anything with the box so if you look into it after a "delete" you might see your old stuff.
Or you might see somebody elses stuff, if the box was reassigned in the meantime.
Technically, you are not allowed to look into your box once you have returned it to the pool, but this is a somewhat weird warehouse with no keys or guards, so you can still do whatever you want.
However, it might cause problems with the new owner of the box, so it's expected that you follow the rules.
13c.
Is there delete in Java
Java has no delete.
We just set the object to NULL.
Once the reference count has become zero the garbage collector will destroy the object.
14.
Setting pointers to NULL after delete
http://stackoverflow.com/questions/1931126/is-it-good-practice-to-null-a-pointer-after-deleting-it
http://stackoverflow.com/questions/9169774/what-happens-in-a-double-delete
Double delete causes an undefined behavior. So setting a pointer to NULL will overcome that.
Deleting a NULL pointer is a Void operation
Before you were owning the block. So deleting it is safe. After first delete you gave up the block. Which means there could be anything in that block and doing a delete again on the block becomes undefined behavior
Setting a pointer to 0 (which is "null" in standard C++, the NULL define from C is somewhat different) avoids crashes on double deletes.
Consider the following:
Foo* foo = 0; // Sets the pointer to 0 (C++ NULL)
delete foo; // Won't do anything
Whereas:
Foo* foo = new Foo();
delete foo; // Deletes the object
delete foo; // Undefined behavior
Under the hood, any memory manager has to maintain some metadata about each block of data it allocates, in a way that allows it to look up the metadata from the pointer that malloc/new returned.
Typically this takes the form of a structure at fixed offset before the allocated block.
This structure can contain a "magic number" -- a constant that is unlikely to occur by pure chance.
If the memory manager sees the magic number in the expected place, it knows that the pointer provided to free/delete is most likely valid.
If it doesn't see the magic number, or if it sees a different number that means "this pointer was recently freed", it can either silently ignore the free request, or it can print a helpful message and abort.
Either is legal under the spec, and there are pro/con arguments to either approach.
If the memory manager doesn't keep a magic number in the metadata block, or doesn't otherwise check the sanity of the metadata, then anything can happen.
Depending on how the memory manager is implemented, the result is most likely a crash without a helpful message, either immediately in the memory manager logic, somewhat later the next time the memory manager tries to allocate or free memory, or much later and far away when two different parts of the program each think they have ownership of the same chunk of memory.
15.
cout << new int[0] << endl; Allocating new with size 0
http://stackoverflow.com/questions/1087042/c-new-int0-will-it-allocate-memory
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements.
From 3.7.3.1/2
The effect of dereferencing a pointer returned as a request for zero size is undefined.
That means you can do it, but you can not legally (in a well defined manner across all platforms) dereference the memory that you get - you can only pass it to array delete - and you should delete it.
16.
Default value of a boolean in a struct
http://stackoverflow.com/questions/3845353/what-will-be-the-default-value-of-an-uninitialized-boolean-value-in-c
http://stackoverflow.com/questions/16782103/initializing-default-values-in-a-struct
The value of the bool is undefined. It will be whatever else was on the stack before it, which is sometimes zeroed out if nothing has used it previously.
But again, it is undefined, which means it can be either true or false.
If you need a default value, you can do:
struct fool_bool {
bool b1;
bool b2;
fool_bool() {
b1 = true;
b2 = false;
} };
In C++ 11 default value can be given inside the struct itself:
struct foo {
bool a = true;
bool b = true;
bool c;
} bar;
17.
Clearing a Char array in C
http://stackoverflow.com/questions/632846/clearing-a-char-array-c
It depends on how you want to view the array. If you are viewing the array as a series of char's then the only way to clear out the data is to touch every entry.
memset is probably the most effective way to achieve this.
On the other hand if you are choosing to view this as a C/C++ null terminated string, setting the first byte to 0 will effectively clear the string.
memset(&arr[0], 0, sizeof(arr));
This is generally the fastest way to take care of this. If you can use C++, consider std::fill instead:
char *begin = &arr;
char *end = begin + sizeof(arr);
std::fill(begin, end, 0);
18.
Re-declaration of default parameter
http://stackoverflow.com/questions/6210450/the-compiler-is-complaining-about-my-default-parameters
You have to specify the default values for the arguments only in the declaration but not in the definition.
class pBase : public sf::Thread {
// ....
void setColor( int _color = -1 );
// ....
} ;
void pBase:: setColor( int _color )
{
// ....
}
19.
IMP: Char array vs NULL terminated String
http://stackoverflow.com/questions/11229477/are-all-char-arrays-automatically-null-terminated
http://stackoverflow.com/questions/12019947/null-termination-of-char-array
http://stackoverflow.com/questions/10050228/c-char-array-null-terminator-location
VERY NICE LINK. Read all examples here
http://c-faq.com/charstring/index.html
char* str1 = "hello world";
As expected, strlen(str1) is equal to 11, and it is null-terminated.
Q: Is it actually allocating an array of length 12 instead of 11, with the 12th character being '\0'?
A: Yes.
Q: But doesn't writing to str2[11] imply that we are writing outside of the allocated memory space of str2, since str2[11] is the 12th byte, but we only allocated 11 bytes?
A: Yes.
Q: Would it be better to use malloc(strlen(str1) + 1) instead of malloc(strlen(str1))?
A. Yes, because the second form is not long enough to copy the string into.
Q: Running this code does not seem to cause any compiler warnings or run-time errors.
A: Detecting this in all but the simplest cases is a very difficult problem.
So the compiler authors simply don't bother.
Only string literals get null-terminated, and that means that char x[]="asdf" is an array of 5 elements.
char arrays are not automatically NULL terminated
Also, WE have to make sure there is space for NULL character.
If you type more than four characters then the extra characters and the null terminator will be written outside the end of the array, overwriting memory not belonging to the array.
This is a buffer overflow.
Q1:
Why doesn't strcat(string, '!'); work?
A1:
There is a very real difference between characters and strings, and strcat concatenates strings.
A character constant like '!' represents a single character.
A string literal between double quotes usually represents multiple characters.
A string literal like "!" seems to represent a single character, but it actually contains two: the ! you requested, and the \0 which terminates all strings in C.
Characters in C are represented by small integers corresponding to their character set values (see also question 8.6).
Strings are represented by arrays of characters; you usually manipulate a pointer to the first character of the array.
It is never correct to use one when the other is expected. To append a ! to a string, use
strcat(string, "!");
Q2:
I'm checking a string to see if it matches a particular value. Why isn't this code working?
char *string;
...
if(string == "value") {
/* string matches "value" */
...
}
A2:
Strings in C are represented as arrays of characters, and C never manipulates (assigns, compares, etc.) arrays as a whole.
The == operator in the code fragment above compares two pointers--the value of the pointer variable string and a pointer to the string literal "value"--to see if they are equal, that is, if they point to the same place.
They probably don't, so the comparison never succeeds.
To compare two strings, you generally use the library function strcmp:
if(strcmp(string, "value") == 0) {
/* string matches "value" */
...
}
Q3:
http://stackoverflow.com/questions/4978056/char-array-declaration-and-initialization-in-c
If I can say
char a[] = "Hello, world!";
why can't I say
char a[14];
a = "Hello, world!";
A3:
ASSIGNMENT vs INITIALIZATION:
That's because your first code snippet is not performing initialization, but assignment
char myarray[4] = "abc"; // Initialization.
myarray = "abc"; // Assignment.
- And arrays are not directly assignable in C.
- The name myarray actually resolves to the address of its first element (&myarray[0]), which is not an lvalue, and as such cannot be the target of an assignment.
- Assignment and initialization are separate things to the language, even though they both use the = character. Arrays are not assignable.
Strings are arrays, and you can't assign arrays directly. Use strcpy instead:
strcpy(a, "Hello, world!");
Q4:
I can't get strcat to work. I tried
char *s1 = "Hello, ";
char *s2 = "world!";
char *s3 = strcat(s1, s2);
but I got strange results.
A4:
- The main problem here is that space for the concatenated result is not properly allocated.
- C compilers allocate memory only for objects explicitly mentioned in the source code (in the case of strings, this includes character arrays and string literals).
- The programmer must arrange for sufficient space for the results of run-time operations such as string concatenation, typically by declaring arrays, or by calling malloc.
- strcat performs no allocation; the second string is appended to the first one, in place.
The first (destination) string must be writable and have enough room for the concatenated result.
Therefore, one fix would be to declare the first string as an array:
char s1[20] = "Hello, ";
Since strcat returns the value of its first argument (s1, in this case), the variable s3 in the question above is superfluous; after the call to strcat, s1 contains the result.
The original call to strcat in the question actually has two problems: the string literal pointed to by s1, besides not being big enough for any concatenated text, is not necessarily writable at all.
Q5.
I'm reading strings typed by the user into an array, and then printing them out later.
When the user types a sequence like \n, why isn't it being handled properly?
A5:
Character sequences like \n are interpreted at compile time.
When a backslash and an adjacent n appear in a character constant or string literal, they are translated immediately into a single newline character.
(Analogous translations occur, of course, for the other character escape sequences.)
When you're reading strings from the user or a file, however, no interpretation like this is performed: a backslash is read and printed just like any other character, with no particular interpretation.
Q6: C vs C++
I think something's wrong with my compiler: I just noticed that sizeof('a') is 2, not 1 (i.e. not sizeof(char)).
A6:
Perhaps surprisingly, character constants in C are of type int, so sizeof('a') is sizeof(int) (though this is another area where C++ differs)
19b.
Why should SCANF never be used
http://stackoverflow.com/questions/12019947/null-termination-of-char-array
This is a great example of why scanf("%s") is dangerous and should never be used.
It doesn't know about the size of your array which means there is no way to use it safely.
Instead, avoid scanf and use something safer, like fgets():
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.
Reading stops after an EOF or a newline.
If a newline is read, it is stored into the buffer.
A terminating null byte ('\0') is stored after the last character in the buffer.
19c.
But I heard that char a[] was identical to char *a.
http://c-faq.com/aryptr/aryptr2.html
- The array declaration char a[6] requests that space for six characters be set aside, to be known by the name ``a''.
That is, there is a location named ``a'' at which six characters can sit
- The pointer declaration char *p, on the other hand, requests a place which holds a pointer, to be known by the name ``p''.
- VERY IMP: ``pointer arithmetic and array indexing [that] are equivalent in C, pointers and arrays are different.'')
3. If they're so different, then why are array and pointer declarations interchangeable as function formal parameters?
- Since arrays decay immediately into pointers, an array is never actually passed to a function.
20a.
Compare/Comparing String in C++
http://stackoverflow.com/questions/9158894/differences-between-c-string-and-compare
if( s == t ) vs if( !s.compare(t) )
std::string::compare() returns an int:
- equal to zero if s and t are equal,
- less than zero if s is less than t,
- greater than zero if s is greater than t.
If you want your first code snippet to be equivalent to the second one, it should actually read:
if (!s.compare(t)) {
// 's' and 't' are equal.
}
VERY IMP:
SHOULD EQUATE TO ZERO
if (str.compare(0, 1, "M") == 0)
The equality operator only tests for equality (hence its name) and returns a bool
20b.
Find Substring
http://www.cplusplus.com/reference/string/string/substr/
std::string str="We think in generalities, but we live in details.";
// (quoting Alfred N. Whitehead)
std::string str2 = str.substr (3,5); // "think"
std::size_t pos = str.find("live"); // position of "live" in str
std::string str3 = str.substr (pos); // get from "live" to the end
21.
Combining vector of strings:
http://stackoverflow.com/questions/1985978/combining-a-vector-of-strings
Use accumulate
int main () {
string str = "Hello World!";
vector<string> vec (10,str);
string a = accumulate( vec.begin(), vec.end(), string("") );
cout << a << endl;
22.
Convert String to Int - C++
http://stackoverflow.com/questions/7663709/convert-string-to-int-c
In C++11 there are some nice new convert functions from std::string to a number type.
So instead of
atoi( str.c_str() )
you can use
std::stoi( str )
where str is your number as std::string.
There are version for all flavours of numbers:
long stol(string), float stof(string), double stod(string)
22a.
Concatenate String with Int
http://stackoverflow.com/questions/191757/c-concatenate-string-and-int
std::string name = "John";
int age = 21;
std::string result;
// 1. with Boost
result = name + boost::lexical_cast<std::string>(age);
// 2. with C++11
result = name + std::to_string(age);
22b.
Convert INT to STRING
string strNum = to_string(number);
23.
Align std out
http://stackoverflow.com/questions/2485963/c-alignment-when-printing-cout
The ISO C++ standard way to do it is to #include <iomanip> and use io manipulators like std::setw
However, that said, those io manipulators are a real pain to use even for text, and are just about unusable for formatting numbers
24.
IMP: Why Pointers
http://stackoverflow.com/questions/22146094/why-should-i-use-a-pointer-rather-than-the-object-itself
I'm coming from a Java background and have started working with objects in C++.
But one thing that occurred to me is that people often use pointers to objects rather than the objects themselves, for example this declaration:
Object *myObject = new Object;
rather than:
Object myObject;
Or instead of using a function, let's say testFunc(), like this:
myObject.testFunc();
we have to write:
myObject->testFunc();
You have two questions bundled up into one. The first is when should we use dynamic allocation (using new)? The second is when should we use pointers?
The important take-home message is that you should always use the appropriate tool for the job.
In almost all situations, there is something more appropriate and safer than performing manual dynamic allocation and/or using raw pointers.
Dynamic allocation
In your question, you've demonstrated two ways of creating an object. The main difference is the storage duration of the object.
When doing Object myObject; within a block, the object is created with automatic storage duration, which means it will be destroyed automatically when it goes out of scope.
When you do new Object(), the object has dynamic storage duration, which means it stays alive until you explicitly delete it.
You should only use dynamic storage duration when you need it. That is, you should always prefer creating objects with automatic storage duration when you can.
The main two situations in which you might require dynamic allocation:
1. You need the object to outlive the current scope - that specific object at that specific memory location, not a copy of it.
If you're okay with copying/moving the object (most of the time you should be), you should prefer an automatic object.
2. You need to allocate a lot of memory, which may easily fill up the stack.
It would be nice if we didn't have to concern ourselves with this (most of the time you shouldn't have to), as it's really outside the purview of C++, but unfortunately we have to deal with the reality of the systems we're developing for.
When you do absolutely require dynamic allocation, you should encapsulate it in a smart pointer or some other type that performs RAII (like the standard containers).
Smart pointers provide ownership semantics of dynamically allocated objects.
Take a look at std::unique_ptr and std::shared_ptr, for example.
If you use them appropriately, you can almost entirely avoid performing your own memory management (see the Rule of Zero).
Pointers
However, there are other more general uses for raw pointers beyond dynamic allocation, but most have alternatives that you should prefer.
As before, always prefer the alternatives unless you really need pointers.
1. You need reference semantics.
Sometimes you want to pass an object using a pointer (regardless of how it was allocated) because you want the function to which you're passing it to have access that that specific object (not a copy of it).
However, in most situations, you should prefer reference types to pointers, because this is specifically what they're designed for.
Note this is not necessarily about extending the lifetime of the object beyond the current scope, as in situation 1 above.