array/main.cpp question

Dec 31, 2015 at 6:50pm
The following code works in its parent program. The array only works if it is initialized in main.cpp. While this is not a problem with one, initializing more
in main.cpp can cause a lot of code bloat. Can you please tell me how initiating multiple arrays is done in c++.

1
2
3
4
5
6
7
8
9
10
11
12
main.cpp
..
int number_of_names(0);
        cout<<"How many names ?";
        cin>>number_of_names;
        int array_size = number_of_names;
        string * my_array = new string[number_of_names]; //setting up array
        //fx calls
 
        input_names(my_array, array_size);
        read_back_names(my_array, array_size);
        sort_names(my_array, array_size);


Thx
Last edited on Dec 31, 2015 at 6:51pm
Dec 31, 2015 at 6:57pm
Could you re-phrase your question? I don't get what you're asking. An example of what you want could help.
Dec 31, 2015 at 7:03pm
The array only works if it is initialized in main.cpp.


So, the following doesn't work for you?

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
#include <algorithm>
#include <iostream>
#include <string>

using std::string;
using std::cout;
using std::cin;

void input_names(string* names, size_t size)
{
    for (size_t i = 0; i < size; ++i)
        getline(cin, names[i]);
}

void print_names(const string* names, size_t size)
{
    for (size_t i = 0; i < size; ++i)
        cout << names[i] << '\n';
}

void sort_names(string* names, size_t size)
{
    std::sort(names, names + size);
}

void run()
{
    size_t number_of_names(0);
    cout << "How many names ?";
    cin >> number_of_names;
    
    const size_t size = number_of_names;
    string* names = new string[size];

    input_names(names, size);
    print_names(names, size);
    sort_names(names, size);
    print_names(names, size);

    delete [] names;
}


int main()
{
    run();
}
Last edited on Dec 31, 2015 at 7:03pm
Jan 2, 2016 at 6:20pm
Ok, so why doesn't my code below work? The array shouldn't go out of scope until main does- right? This example would clear up a lot for me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>

using namespace std;

void initialize_array()
{
	int size(10);
	string * string_array = new string[size];
}
int main()
{

	initialize_array();
	string_array [2] = "Tom";
	delete[] string_array;
	return 0;
}
Last edited on Jan 2, 2016 at 6:28pm
Jan 2, 2016 at 6:25pm
Because the dynamically allocated string_array that you create in initialize_array() can not be seen by main. Main doesnt know it exists.
Jan 2, 2016 at 6:48pm
closed account (E0p9LyTq)
string_array is a variable only visible within your initialize_array() function. string_array goes out of scope as soon as your initialize_array() function returns. The memory allocated, though, is still allocated. main() can not access the memory allocated.

A memory leak.
Jan 2, 2016 at 7:15pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>

// A function which allocates an array of size std::strings and returns
// a pointer to the array.
std::string* alloc_array(std::size_t size)
{
    return new std::string[size];
}

int main()
{
    std::size_t capacity = 10;
    std::string* strings = alloc_array(capacity);

    strings[2] = "Tom";

    delete [] strings;
}
Jan 3, 2016 at 5:05pm
Yes, I tried returning the pointer to the array before you posted but couldn't get it to work. Even though your code does, here's mine:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>

using namespace std;

string initialize_array(int size)
{
	string * string_array = new string[size];
	string_array [3] = 4;
	return  string_array;
}

int main()
{

	string * string_array = initialize_array(10);
	string_array [2] = "Tom";

	delete[] * string_array;
	return 0;
}
Last edited on Jan 3, 2016 at 6:44pm
Jan 3, 2016 at 7:12pm
Yes, I tried returning the pointer to the array before you posted but couldn't get it to work.
string initialize_array(int size)
A string is not a pointer.

Should be:string * initialize_array(int size)
Jan 3, 2016 at 8:09pm
In this case is string * pointer type just as int function is type int in a fx or type double, etc.

Also why does the array persist after scope terminates in the function?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>

using namespace std;

string * initialize_array(int size)
{
	string * string_array = new string[size];
	string_array [3] = "Orange";
	return  string_array;
}

int main()
{

	string * string_array = initialize_array(10);
	string_array [2] = "Tom";
	cout<<string_array[3];
	delete[] string_array;
	return 0;
}


Also is line 9 a typo - should be strings instead of string?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include <iostream>
#include <string>

// A function which allocates an array of size std::strings and returns
// a pointer to the array.
std::string* alloc_array(std::size_t size)
{
    return new std::string[size];
}

int main()
{
    std::size_t capacity = 10;
    std::string* strings = alloc_array(capacity);

    strings[2] = "Tom";

    delete [] strings;
}
Last edited on Jan 3, 2016 at 9:04pm
Jan 4, 2016 at 2:29pm
why does the array persist after scope terminates in the function?

Because you've dynamically allocated the memory on the heap. That's the whole point (*) of dynamic memory allocation - that you control how long the memory persists for.

(*) Well, OK, one of the points.
Jan 5, 2016 at 12:57am
The code output was reconstructed with pointers for giggles. The output shows that the init_array fx generates and returns to main the address of the first position of the initilized array, which is supposed to happen. Some people here have posted that you can't see some arrays from main. However in this exercise I can manipulate string_array from main even within other functions. So I am not sure what I am missing there.

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
#include<iostream>

using namespace std;

string * init_array(int size)
{
string * string_array = new string[size];
cout<<"generated in fx: "<<string_array<<endl;
return string_array;
}

string do_more(string * string_array)
{
	*(string_array + 4) = "calcitonin";
}

string print_do_more(string * string_array)
{
	*(string_array+5) = "lexus";
	*(string_array+7) = "peach";
	cout<<endl;
	cout<<*(string_array+ 5)<<endl;
	cout<<*(string_array + 4)<<endl;
}

void delete_mem(string * string_array)
{
	delete[] string_array;      // [] refers to memory
}

int main()
{
	int size(10);
	string * string_array;
	string_array = init_array(size);
	cout<<"returned to main: string_array  "<<string_array;
	do_more(string_array);
	print_do_more(string_array);
	cout<<*(string_array+7);

    delete_mem(string_array);

	return 0;
}


generated in fx: 0xaf1438
returned to main: string_array  0xaf1438
lexus
calcitonin
peach
Last edited on Jan 5, 2016 at 12:58am
Jan 5, 2016 at 1:10am
The code output was reconstructed with pointers for giggles.

Your code is riddled with bugs that cause undefined behavior. do_more and print_do_more both promise to return objects and do not.

Some people here have posted that you can't see some arrays from main.

I believe that was.. you.
Jan 5, 2016 at 10:19am
Some people here have posted that you can't see some arrays from main.

Um... could you be any more vague?

C++ has well-defined rules about variable scope.

C++ has well-defined rules about the persistence of memory on the stack.

C++ has well-defined rules about the persistence of memory on the heap.

You really should make the effort to learn them, because you're only going to carry on making mistakes if you don't.
Last edited on Jan 5, 2016 at 10:19am
Jan 5, 2016 at 3:53pm
Ok, thx, I guess I had that coming.

Maybe I misunderstood abt

Because the dynamically allocated string_array that you create in initialize_array() can not be seen by main. Main doesn't know it exists.


1
2
3
4
5
6
string * init_array(int size)
{
string * string_array = new string[size];
cout<<"generated in fx: "<<string_array<<endl;
return string_array;
}


I can access the array from anywhere in the program including main. Maybe I don't understand what the author means by "see".


As for:

C++ has well-defined rules about variable scope.

C++ has well-defined rules about the persistence of memory on the stack.

C++ has well-defined rules about the persistence of memory on the heap.


-ok, appreciate the redirection.

Last edited on Jan 5, 2016 at 3:59pm
Jan 5, 2016 at 5:02pm
I can access the array from anywhere in the program including main. Maybe I don't understand what the author means by "see".

That quote was in response to your second post in this thread. That post contained an earlier version of your code, in which initialize_array was declared as void, so it wasn't returning the pointer. Since the function didn't return the pointer to the dynamically allocated array, there was no way for the calling code to access that memory.

It was in a much later post of yours that you showed us the version of init_array that actually returned the pointer.
Last edited on Jan 5, 2016 at 5:03pm
Jan 5, 2016 at 9:18pm
Got it Mikey Boy. Thanks! No longer a mystery.
Last edited on Jan 5, 2016 at 9:22pm
Jan 5, 2016 at 9:22pm
Cire (et al) I have eliminated 2 of the obvious bugs in your post mentioning my code riddled with bugs. Are there any more?
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
#include<iostream>

using namespace std;

string * init_array(int size)
{
	string * string_array = new string[size];
	cout<<"generated in fx: "<<string_array<<endl;
	return string_array;
}

void do_more(string * string_array)
{
	*(string_array + 4) = "calcitonin";
}

void print_do_more(string * string_array)
{
	*(string_array+5) = "lexus";
	*(string_array+7) = "peach";
	cout<<endl;
	cout<<*(string_array+ 5)<<endl;
	cout<<*(string_array + 4)<<endl;
}

void delete_mem(string * string_array)
{
	delete[] string_array;      // [] refers to memory created with NEW
	string_array = NULL;	    // nulling the ptr to avoid dangling
}

int main()
{
	int size(10);
	string * string_array;
	string_array = init_array(size);
	cout<<"returned to main: string_array  "<<string_array;
	do_more(string_array);
	print_do_more(string_array);
	cout<<*(string_array+7);

        delete_mem(string_array);

	return 0;
}
Last edited on Jan 5, 2016 at 9:29pm
Topic archived. No new replies allowed.