array/main.cpp question

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
Could you re-phrase your question? I don't get what you're asking. An example of what you want could help.
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
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
Because the dynamically allocated string_array that you create in initialize_array() can not be seen by main. Main doesnt know it exists.
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.
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;
}
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
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)
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
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.
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
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.
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
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
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
Got it Mikey Boy. Thanks! No longer a mystery.
Last edited on
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
Topic archived. No new replies allowed.