Grow Array Size

Write here if you have problems with your C++ source code

Moderator: Board moderators

Post Reply
Fresh
New poster
Posts: 46
Joined: Mon Apr 15, 2002 10:42 am
Contact:

Grow Array Size

Post by Fresh »

Hi,

Is there any solution to grow an dynamic array without free and reallocate it, then recopy the original value? I did some experiment as below, only works for 'int'(how good/reliable is it?) and nop the 'char'. Help!

[cpp]
void main()
{
int i, *pnum, *num;
char *pstr, *str;

// Grow 'int' type array
num = new int[5];
for (i=0; i<5; i++)
num = i;
//endfor

for (i=0; i<5; i++)
printf("%d%c",num,(i == 4) ? '\n':' ');
//endfor

pnum = &num[4];
pnum = new int[10];
for (i=5; i<8; i++)
num = i * 3;
//endfor

for (i=0; i<8; i++)
printf("%d%c",num,(i == 7) ? '\n':' ');
//endfor

// Grow 'char' type array
str = new char[5];
strcpy(str,"abcd");
printf("str = %s\n",str);
pstr = &str[3];
pstr = new char[100];
strcpy(pstr,"12345678");
printf("str = %s\n",str);
}
[/cpp]

The output:
[cpp]
0 1 2 3 4
0 1 2 3 4 15 18 21
str = abcd
str = abcd
[/cpp]


One more thing, how to get the number of array size(element), passed as parameter?

[cpp]
int getBufSize(char *buf)
{
// Output should 1024, nop 4
printf("sizeof(buf) = %d\n",sizeof(buf));
}

void main(int argc, char *argv[])
{
int i, *pnum, *num;
char *pstr, *str;

char buf[1024];

printf("sizeof(buf) = %d\n",sizeof(buf));
getBufSize(buf);
}
[/cpp]

-novice :cry:

Jordan Gordeev
New poster
Posts: 14
Joined: Tue Nov 12, 2002 6:04 pm
Location: Bulgaria

Post by Jordan Gordeev »

Your 'growing' code should not work as the two parts of the array, the one you allocate with
[cpp]num = new int[5];[/cpp]
and the one allocated with
[cpp]pnum = new int[10];[/cpp]
will be at different (not near) addresses in the general case.

[cpp]pnum = &num[4];[/cpp]
does nothing when followed by
[cpp]pnum = new int[10];[/cpp]
as the latter will find memory region big enoufh to hold 10 ints end assign its addess to pnum, no matter what its old value was.
One more thing, how to get the number of array size(element), passed as parameter?
You can't get it.
sizeof(buf) when buf is char* will give you the size of the char* type which is 4 bytes (32 bits).

When you allocate an array with new[] the array size is stored somewhere so you can use delete[] without passing the array size, but you cannot get this size information.

I suggest you use std::vector<>s if you can afford a little speed degradation as vectors grow automatically and always know their size.

Hope I was useful.

arnsfelt
New poster
Posts: 44
Joined: Wed Oct 17, 2001 2:00 am
Location: Denmark
Contact:

Post by arnsfelt »

try realloc()

suman
New poster
Posts: 45
Joined: Fri Oct 19, 2001 2:00 am
Contact:

Why don't you try "vector"

Post by suman »

Hi,
Your approach is good but somewhat incomplete. The thing you are trying to do is already there in the STL (Standard Template Library). Its nicer then you may anticipate. Try the following.

[cpp]
#include <cstdio>
#include <iostream>
#include <vector>

int main()
{
// integer array
vector<int> a;

for(i=0;i<10;++i)
a.push_back(i+1);

for(i=0;i<a.size();++i)
cout << a;

// character array, this time making it of size 20
vector<char> b(20);

for(i=0;i<26;++i)
{
b = 'a'+i;
if(b.size() < i ) b.resize(30);
}

for(i=0;i<b.size();++i)
cout << b;

return 0;
}
[/cpp]

Note:
> I have written the code right here, so may have error.
> Use VC++6.0 or borland C++ 5.0 or gnu c++ 2.95
> See STL documentations in MSDN library or the web STL Library Guide
> I am going to post an Array and Array2D implementation under the algorithm thread. Check that out.

- Suman

Fresh
New poster
Posts: 46
Joined: Mon Apr 15, 2002 10:42 am
Contact:

...

Post by Fresh »

Hi,

Another question about pointer. My simple code as below, why ptr still hold the value after b was freed? What happen to elements[0-3]? Did they completely freed?

[cpp]
char *GetString()
{
char *ptr, *b = new char[10];

b[4] = 'F';
b[5] = 'r';
b[6] = 'e';
b[7] = 's';
b[8] = 'h';
b[9] = '\0';

ptr = &b[4];
delete b;
return ptr;
}

void main()
{
char *ptr = GetString();
printf("%s\n",ptr);
delete ptr;
}
[/cpp]

-novice :roll:

Yarin
Problemsetter
Posts: 112
Joined: Tue Sep 10, 2002 5:06 am
Location: Ume
Contact:

Post by Yarin »

A pointer is simple an integer. When you do ptr=&b[4], ptr will contain the address to the fourth element in b, which is just a number. When you later free the b array, the value in ptr will of course not change - it will still contain the same number. However, now this pointer points to memory which your program is not in control of!

This is called a "dangling pointer" and is one of the dangers of pointers (which is one reason why explicit pointers doesn't exist in Java for instance). If you start reading or writing from this pointer - which you do in your printf statement - you could very well try to print information from another application (although if you try this, you should get "invalid memory reference" or some such).

Thus: NEVER ever access a pointer which points to some part of the memory you just have freed. That's a standard rule.

Fresh
New poster
Posts: 46
Joined: Mon Apr 15, 2002 10:42 am
Contact:

...

Post by Fresh »

I don't want to break the rule. The code below convert my BigInteger to a base (2 - 64) string. The method#1 might faster than the #2 but ... any comment?

Method#1
[cpp]
static const char *BASE_DIGIT = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";

char *BigInteger::toString(const unsigned int radix = 10)
{
int i, remaider;
char *str = NULL;

str = (char*)malloc(1024 * 8);

i = 1024 * 8 - 1;
str[i--] = '\0';
while (this != 0) // operator overloading?
{ remaider = this % radix;
this /= radix;
str[i--] = BASE_DIGIT[remaider];
}

if (sign == NEGATIVE)
str[i--] = '-';
//endif

return &str[i + 1];
}
[/cpp]

Method#2
[cpp]
char *BigInteger::toString(const unsigned int radix = 10)
{
int i, q, remaider;
char ch, *str = NULL;

str = (char*)malloc(1024 * 8);

i = 0;
while (this != 0) // operator overloading?
{ remaider = this % radix;
this /= radix;
str[i++] = BASE_DIGIT[remaider];
}

if (sign == NEGATIVE)
str[i++] = '-';
//endif

// Reverse
for (q = 0; q < i/2; q++)
{ ch = str[q];
str[q] = str;
str = ch;
}
str = '\0';
return str;
}
[/cpp]

-novice :cry:

Rodrigo
New poster
Posts: 14
Joined: Sun Jul 07, 2002 12:03 am
Location: Brazil
Contact:

Post by Rodrigo »

If I understood your code, it looks to me that you're not returning the zeroth element of the array in the first one. This could cause trouble when freeing the returned string.

Rodrigo

suman
New poster
Posts: 45
Joined: Fri Oct 19, 2001 2:00 am
Contact:

Careful While Using pointer

Post by suman »

Hi,
What are you trying to do is really dangerous. In the code you are what you are trying will do the following,

[cpp]
BigInteger a(

Fresh
New poster
Posts: 46
Joined: Mon Apr 15, 2002 10:42 am
Contact:

...

Post by Fresh »

Hi,

Another simple question, what is the different (faster) between using pointer and set element index, as below? I dont know... :-?

[cpp]
char str[100] = "abcdefghijklmnopqrstuvwxyz";

for (int i=0; str; i++)
printf("%c", str);
[/cpp]

[cpp]
char *ptr, str[100] = "abcdefghijklmnopqrstuvwxyz";

ptr = &str[0];
for (int i=0; *ptr; i++)
printf("%c", *ptr++);
[/cpp]

I didn't compile those code, hope u' understand my problem :wink:

-novice

Yarin
Problemsetter
Posts: 112
Joined: Tue Sep 10, 2002 5:06 am
Location: Ume
Contact:

Post by Yarin »

With optimizations turned off, the pointer method should be faster. With optimization, it shouldn't matter - the compiler will change the first version into the second one (if possible, if the variable is used for other things as well it might be harder).

Ivan Golubev
Experienced poster
Posts: 167
Joined: Fri Oct 19, 2001 2:00 am
Location: Saint Petersburg, Russia

Post by Ivan Golubev »

Yarin wrote:With optimizations turned off, the pointer method should be faster.
I'm not sure about this -- if pointer isn't register variable speed will be nearly the same.

Anyway, printf("%s", str); will be faster than outputting character by character.

Alansoft
New poster
Posts: 5
Joined: Mon Feb 03, 2003 11:31 pm
Location: Brazil
Contact:

Post by Alansoft »

Only a tip:

[cpp]
char *ptr, str[100] = "abcdefghijklmnopqrstuvwxyz";
ptr = &str[0];
[/cpp]

Is the same of:
[cpp]
char *ptr, str[100] = "abcdefghijklmnopqrstuvwxyz";
ptr = str;
[/cpp]

Please correct me if I'm wrong!
[]'s

Alan

Dominik Michniewski
Guru
Posts: 834
Joined: Wed May 29, 2002 4:11 pm
Location: Wroclaw, Poland
Contact:

Post by Dominik Michniewski »

Alansoft: you have right - it's the same ....

Ivan: Speed of two solutions is near the same. But, without optimalization, operations on pointers are faster then indexing - I think that pointer in this case *is* register variable - as counter of loop ... Why? On pointers we have address in memory and read data from it. In second case we have address in memory too, but we must add some value to it, and next read data .... So we are doing some addition in every step of loop ....

If I'm wrong - can anyone correct me ?

BTW. I prefer to use second version - on pointers. Simple functions which operating on strings looks nicer to me , when I coded it in this way ... But If programmer is not so familiar with pointers - indexing is better :)

Regards
Dominik

Post Reply

Return to “C++”