Page 1 of 1

Grow Array Size

Posted: Wed Nov 20, 2002 5:44 am
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:

Posted: Wed Nov 20, 2002 8:44 am
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.

Posted: Wed Nov 20, 2002 10:06 am
by arnsfelt
try realloc()

Why don't you try "vector"

Posted: Wed Nov 20, 2002 12:39 pm
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

...

Posted: Tue Nov 26, 2002 4:11 am
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:

Posted: Tue Nov 26, 2002 5:25 am
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.

...

Posted: Tue Nov 26, 2002 8:51 am
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:

Posted: Tue Nov 26, 2002 5:43 pm
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

Careful While Using pointer

Posted: Tue Nov 26, 2002 9:16 pm
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(

...

Posted: Mon Dec 02, 2002 3:33 pm
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

Posted: Mon Dec 02, 2002 5:54 pm
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).

Posted: Mon Dec 02, 2002 9:24 pm
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.

Posted: Sun Feb 09, 2003 3:07 am
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!

Posted: Mon Feb 10, 2003 10:00 am
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