AHHH! worked on this too long.. whats up with the malloc

I cannot figure out the 2 last errors I am getting.
Someone PLEASE HELP!
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
//#include <stdio.h>
//#include <string.h>
//#include <stdlib.h>

#include <string>
#include <vector>
#include <iostream>
#include <sstream>

using namespace std;

//#define SIZE 100

const int SIZE = 100;

//returns a malloc'd string which must be freed

char *foo(int x){
    
    //string string_A[10];
    //string foo(int x,string string_A){
    
	char *string = malloc(10);
	sprintf(string, "%d", x);
	return string;
}


/* main() contains a lot of code. First, take this code and convert it to C++.
 * This means replacing the C style strings with C++ style strings, swapping out the
 * I/O from C style to C++ style, etc.
 */

int main(int argc, char **argv){
    
    /*******************************************************	//COMPLETE
     char *string1 = "This is a string";
     char *string2 = "This is another string";
     char *string3 = "This is a string";
     char string4[SIZE];
     *******************************************************/
    
	string string1 = "This is a string";
	string string2 = "This is another string";
	string string3 = "This is a string";
	string string4[SIZE];
    
    
    //stack is for automatic variables -- also known as local variables
    //heap is for dynamic variables -- anything created with malloc
    
    /********int array[SIZE];**************/				//COMPLETE
	vector<int> array1(SIZE);
    
    
	//FIX THIS ||||||||| FIX THIS ||||||||| FIX THIS |||||||| FIX THIS
	int *pointer = (int *)malloc(SIZE * sizeof(int));
    
    
	//array initializer statements
    /************int init[] = {1,2,3,4,5,6};****************/		 //COMPLETE
    
	vector<int> init(6);
	for(int i = 1; i < 7; i++){
		init[i]=i;
	}
    
    
    
    
    
    
    /************* fprintf(stdout, "string1 = %s\nstring2 = %s\nstring3 = %s\n", string1, string2, string3); **************/ //COMPLETE
    
	cout << "string 1 = " << string1 << endl << "string 2 = " << string2 << endl << "string 3 = " << string3 << endl;
    
    
    
    /* prompt, and take in a new string, no more than SIZE characters */
    /************************************************************************************* //COMPLETE
     fprintf(stdout, "Please enter a string, and hit return: ");
     fgets(string4, SIZE, stdin);
     fprintf(stdout, "string4 = %s", string4);
     **************************************************************************************/
    
	cout << "Please enter a string, and hit return : ";
	cin >> string4;
	cout << "string4 = " << string4 << endl;
    
    
    
    /************************************************************************************** //COMPLETE
     if (strcmp(string1, string2) == 0){
     //they are equal
     fprintf(stdout, "string1 = string2\n");
     }
     else{
     fprintf(stdout, "string1 %c string2\n",(strcmp(string1, string2) > 0) ? '>' : '<');
     }
     *************************************************************************************/
    
	if(string1==string2){
		cout << "String1 = String2" << endl;
	}
	else if(string1>string2){
		cout << "String1 > String2" << endl;
	}
	else{
		cout << "String1 < String2" << endl;
	}
    
    
    /****************************************** //COMPLETE
     this is equivalent
     x = cond ? a : b;
     to this
     if(cond)
     x = a;
     else
     x = b;
     ******************************************/
     
     
     /*********************************************** //COMPLETE
     if (strcmp(string1, string3) == 0){
     // they are equal
     //fprintf(stdout, "string1 = string3\n");
     }
     else{
     fprintf(stdout, "string1 %c string3\n", (strcmp(string1, string3) > 0) ? '>' : '<');
     }
     ***********************************************/
    
	if(string1==string3){
		cout << "String1 = String3" << endl;
	}
	else if(string1>string3){
		cout << "String1 > String3" << endl;
	}
	else{
		cout << "String1 < String3" << endl;
	}
    
    /*********************************************** //COMPLETE
     if (strcmp(string3, string2) == 0){
     
     fprintf(stdout, "string3 = string2\n");
     }
     else{
     fprintf(stdout, "string3 %c string2\n", (strcmp(string3, string2) > 0) ? '>' : '<');
     }
     ***********************************************/
    
    if(string2==string3){
		cout << "String2 = String3" << endl;
	}
	else if(string2>string3){
		cout << "String2 > String3" << endl;
	}
	else{
		cout << "String2 < String3" << endl;
	}
    
    
    /**********************************************        //COMPLETE
     walk through the arrays, initialize, and then walk through again and print out
     for (int i = 0; i < SIZE; ++i){
     array[i] = i;
     pointer[i] = i;
     }
     **********************************************/
    
	for (int i = 0; i < SIZE; ++i){
		array1[i] = i;
	}
    
    /************************************************************************** //COMPLETE
     for (int i = 0; i < SIZE; ++i){
     fprintf(stdout, "%d\t%d\n", array[i], pointer[i]);
     }
     ***************************************************************************/
    
	for(int i = 0; i < SIZE; ++i){
		cout << array1[i] << " " << pointer[i] << endl;
	}
    
	/* clean up my mess */
	//free(pointer);
	delete[] pointer;
    
    
	return 0;
}



Lines 23 and 87 are my trouble lines
Last edited on
Line 23: malloc() returns a 'void *'. Implicitly casting from void * to another pointer type is illegal in C++. MAke the cast explicitly.
Line 87: string4 is an array of strings, not a string.

1
2
3
int *pointer = (int *)malloc(SIZE * sizeof(int));
//...
delete[] pointer;
Bad. Very bad.
Last edited on
What do I have to change line 23 to be to make it work in cpp?
My general comment is that you are mixing C and C++, which gives potential for confusion.

Either write it in C with malloc & free along with char arrays, or write it in C++ with new & delete along with strings.

Edit :

using namespace std;

sprintf(string, "%d", x);

string is a C++ type from the std library as in std::string, so this demonstrates where the confusion starts .....
Last edited on
What do I have to change line 23 to be to make it work in cpp?
Simply write this:
char *string = new char[10];

and this:
int *pointer = new int[SIZE];

the best is not to use malloc in a C++ environment
closed account (zb0S216C)
As helios pointed out, mixing both "malloc( )" and "delete[]" is a bad idea. The reason behind this is that "malloc( )" normally allocates memory in the form of a linked-list (which can cause fragmentation), whereas "new" allocates memory in the form a contiguous block. When "delete[]" is applied to a block allocated with "malloc( )", who knows what will happen.

Interestingly, however, "new" may [implementation-defined] use "malloc( )" internally.

Wazzak
Last edited on
Both malloc and new are required to return contiguous blocks of memory. I can't imagine a memory manager that didn't. "Hey! You'll need to use this part of memory to store this part of your array, and this part of memory over here to store the rest, so you can just forget about using pointer arithmetic!"

Besides the fact that the internals of malloc/free and new/delete may be entirely incompatible, malloc/free still fail to invoke constructors/destructors. Mixing the two is an obvious source of buggy code and you certainly can't count on that behavior being portable across compilers.

nterestingly, however, "new" may [implementation-defined] use "malloc( )" internally.


Do you have a source for this? I'm curious, because I thought new was just a wrapper around malloc, plus some features to make it a little easier to use.
closed account (zb0S216C)
cire wrote:
"Both malloc and new are required to return contiguous blocks of memory. I can't imagine a memory manager that didn't."

This is a extract from The C Programming Language, 2nd Edition:

"Since other activities in the program may also request space without calling this allocator, the space that malloc manages may not be contiguous. Thus its free storage is kept as a list of free blocks. Each block contains a size, a pointer to the next block, and the space itself. The blocks are kept in order of increasing storage address, and the last block (highest address) points to the first."

Whether this behaviour has changed in C++ is unknown to me. Either way, it's still a linked-list implementation.

ResidentBiscuit wrote:
"Do you have a source for this?"

Sure: 18.6.1.1 Single-object forms, Paragraph 4:

Standard wrote:
"Default behavior:
— Executes a loop: Within the loop, the function first attempts to allocate the requested storage.
Whether the attempt involves a call to the Standard C library function malloc is unspecified."


Wazzak
Last edited on
Both of you are saying things are are true. malloc() does return blocks of contiguous memory, and internally it likely does manage memory as a linked list of blocks.
Like cire pointed out, malloc() absolutely has to return blocks of contiguous memory, or it would be completely impossible to do anything with anything it returns. How would you know where a piece ends and where the next one begins, otherwise?
Last edited on
Whether this behaviour has changed in C++ is unknown to me. Either way, it's still a linked-list implementation.


Returning contiguous blocks of memory and managing only memory contained in one contiguous block are entirely different things, and neither new nor malloc is required to do the latter.

Topic archived. No new replies allowed.