Access violation on copying array contents.

D

dbuser

Dear experts:
Hope you can point my error here. This function of mine receives an
array of length 32 and then the for loop adds some scrambled characters
at patterns. I think, I can not read the array w[] beyond 32 , but dont
know how to achieve the result. Thanks a lot for help !

void scramble( char *w, int key)
{
x = key; // key = (0-9)
int len = strlen(w);
cout << "length is:" << len << endl; // 32
len = (len + len/x); // 48
cout << "length is:" << len << endl;
char s[] = "@#$"; //array to hold scramble characters
int n = strlen(s);
int i,j,k,m=0;
char * c;
c = new char[len+1];
memset(c, 0, sizeof(c));
//if (c == NULL) exit(1);
for (i=0,j=0,k=0; i<len-1; i++){
if(k<x) {
c[j++] = w;k++;
}
else {
if(m<n)
c[j++] = s[m++];
else {
c[j++] = s[0]; m = 1;}
c[j++]=w; k=1; }
}
cout << "scrambled output is :" << c << endl;
delete c;
}

The output is this, which is desired but it has run time error as
mentioned.
input is : ba ced fhgi kzl nmpo qsr tvuxwzy
scrambled output is :ba@ c#ed$ f@hg#i $kz@l #nm$po@ q#sr$ t@vu#xw$zy@
 
V

Victor Bazarov

dbuser said:
Hope you can point my error here. This function of mine receives an
array of length 32 and then the for loop adds some scrambled characters
at patterns. I think, I can not read the array w[] beyond 32 , but dont
know how to achieve the result. Thanks a lot for help !

void scramble( char *w, int key)

If 'w' is the array the bounds of which you're not supposed to cross,
then this function needs to know the bounds -- pass the actual size of
that array into the function, as another argument.
{
x = key; // key = (0-9)

Where is 'x' declared? Is it a global variable?
int len = strlen(w);
cout << "length is:" << len << endl; // 32

Is '32' what it prints out?
len = (len + len/x); // 48

What does '48' mean? x == 2? What is 'len' now?
cout << "length is:" << len << endl;

Does it print 48 here?
char s[] = "@#$"; //array to hold scramble characters

Four letters is the size of your 's' array.
int n = strlen(s);

n is 3.
int i,j,k,m=0;
char * c;

Why not merge the two statements into one?
c = new char[len+1];
memset(c, 0, sizeof(c));

sizeof(c) is 4. You really need to do 'memset(c, 0, len+1)' here.
//if (c == NULL) exit(1);
^^^^^^^^^^^^^^^^^^^^^^^^^
Get rid of this comment, it has no value.
for (i=0,j=0,k=0; i<len-1; i++){
if(k<x) {
c[j++] = w;k++;


So, you copy the characters if 'k' is smaller than the 'key'. IOW, you
leave up to 'key' characters unchanged.
}
else {
Otherwise...

if(m<n)
c[j++] = s[m++];

You insert a scrambled character until they are all used up (m>=n)
else {
c[j++] = s[0]; m = 1;}

Otherwise you start over...
c[j++]=w; k=1; }


... and still append the source character...
}
cout << "scrambled output is :" << c << endl;
delete c;

delete[] c;
}

The output is this, which is desired but it has run time error as
mentioned.
input is : ba ced fhgi kzl nmpo qsr tvuxwzy
scrambled output is :ba@ c#ed$ f@hg#i $kz@l #nm$po@ q#sr$ t@vu#xw$zy@

Well, your calculation of 'len' may be a bit flawed. Try adding 1 to it.

V
 
D

Dan Cernat

dbuser said:
Dear experts:
Hope you can point my error here. This function of mine receives an
array of length 32 and then the for loop adds some scrambled characters
at patterns. I think, I can not read the array w[] beyond 32 , but dont
know how to achieve the result. Thanks a lot for help !

void scramble( char *w, int key)
{
x = key; // key = (0-9)
int len = strlen(w);
cout << "length is:" << len << endl; // 32
len = (len + len/x); // 48
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ replace with
int newLen = (len + len/x);
cout << "length is:" << len << endl;
char s[] = "@#$"; //array to hold scramble characters
int n = strlen(s);
int i,j,k,m=0;
char * c;
c = new char[len+1];
^^^^^^^^^^^^^^^^^^^ c = new char[newLen + 1];
memset(c, 0, sizeof(c));
^^^^^^^ sizeof(c) is 4 on 32 bit machines
memset(c, 0, newLen + 1);
//if (c == NULL) exit(1);
for (i=0,j=0,k=0; i<len-1; i++){
if(k<x) {
c[j++] = w;k++;
}
else {
if(m<n)
c[j++] = s[m++];
else {
c[j++] = s[0]; m = 1;}
c[j++]=w; k=1; }
}
cout << "scrambled output is :" << c << endl;
delete c;

^^^^^^^^^^^^^^^^^^^^
delete[] c;
}

The output is this, which is desired but it has run time error as
mentioned.
input is : ba ced fhgi kzl nmpo qsr tvuxwzy
scrambled output is :ba@ c#ed$ f@hg#i $kz@l #nm$po@ q#sr$ t@vu#xw$zy@

work on the indentation style. also, write one statement per line.

your for loop was running 48 times, and J was incremented 2 some times
(that is how it works) so you were writing past the end of newly
allocated memory for c

/dan
 
D

dbuser

Thanks a lot for your valuable suggestions. I corrected mistakes but to
fix run time error, I had to read source array upto its own length like
this:
for (i=0,j=0,k=0,p=0; i<newLen,p<len; i++,p++){
if(k<x) {
c[j++] = w[p];k++;
}
else {
if(m<n)
c[j++] = s[m++];
else {
c[j++] = s[0];
m = 1;
}
c[j++]=w[p];
k=1;
}
}
 
T

Thomas J. Gritzan

dbuser said:
Thanks a lot for your valuable suggestions. I corrected mistakes but to
fix run time error, I had to read source array upto its own length like
this:
for (i=0,j=0,k=0,p=0; i<newLen,p<len; i++,p++){
^^^^^^^^^^^^^^
Do you mean (i<newLen && p<len) or (i<newLen || p<len)?
The comma operator throws away the result of the first part.
if(k<x) {
c[j++] = w[p];k++;
}
else {
if(m<n)
c[j++] = s[m++];
else {
c[j++] = s[0];
m = 1;
}
c[j++]=w[p];
k=1;
}
}

Th.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top