Trying to populate a 2D char array. This code should just work:
char FilenamesBuffer[3][64] = {{"test1"},{"test2"},{"test3"}};
char FilenamesBufferTest[3][64] = {{"unwritten1"},{"unwritten2"},{"unwritten3"}};
//print destination buffer before write
for (i = 0; i < 3; i++)
{
for (j = 0; j < 64; j++)
{
Serial.printf("%c", *((char*)FilenamesBufferTest+(i*64) + j));
}
Serial.println();
}
Serial.println();
//copying
for (i = 0; i < 3; i++)
{
Serial.print("copying ");Serial.println(i);
snprintf(*(FilenamesBufferTest+i*64), 64, "%s", *(FilenamesBuffer+i*64));
}
Serial.println();
//print destination buffer after write
for (i = 0; i < 3; i++)
{
for (j = 0; j < 64; j++)
{
Serial.printf("%c", *((char*)FilenamesBufferTest+(i*64) + j));
}
Serial.println();
}
Outputs:
unwritten1
unwritten2
unwritten3
copying 0
copying 1
copying 2
test1ten1
unwritten2
unwritten3
Looks like only the first row gets copied. I tried casting the char array addresses as (char**) which doesn't seem like it should make a difference. But it breaks the program.
snprintf(*((char**)FilenamesBufferTest+i*64), 64, "%s", *((char**)FilenamesBuffer+i*64));
Output:
unwritten1
unwritten2
unwritten3
copying 0
and then strangely
snprintf(((char*)FilenamesBufferTest+i*64), 64, "%s", ((char*)FilenamesBuffer+i*64));
works
You're confusing yourself by using pointer arithmetic to access arrays -- don't do it; use array accesses instead.
So when you do:
*(FilenamesBufferTest+i*64)
That's the same as FilenamesBufferTest[i*64] which is out-of-bounds when i is anything other than 0. You want FilenamesBufferTest[i], which would be:
*((char *)FilenamesBufferTest+i*64)
if you really want to do the explicit arithmetic, but that is much harder.
Related
I am trying to create a merge function for two array structures in c++ but am coming up with a bad access error that I don't know how to solve. The error comes up when I am trying to swap the element in the smaller array into the larger, merged array. The code doesn't even go through a single iteration. All three of i, j, and k remain at 0. Any help would be greatly appreciated! Here is the code:
struct Array
{
int *A;
int size;
int length;
};
void display(Array arr){
for (int i = 0; i < arr.length; i++)
std::cout << arr.A[i] << std::endl;
}
Array merge(Array arr1, Array arr2){
Array arr3;
arr3.length = arr1.length + arr2.length;
arr3.size = arr1.length + arr2.length;
int i = 0, j =0, k =0;
while(i <arr1.length && j < arr2.length){
if (arr1.A[i] < arr2.A[j])
{
arr3.A[k] = arr1.A[i]; //(The error is displayed here: Thread 1: EXC_BAD_ACCESS (code=1, address=0x28))
k++;
i++;
}
else if (arr2.A[j] < arr1.A[i])
{
arr3.A[k] = arr2.A[j];
k++;
j++;
}
}
for (; i< arr1.length; i++)
{
arr3.A[k]=arr1.A[i];
k++;
}
for (; i< arr2.length; j++)
{
arr3.A[k]=arr2.A[j];
k++;
}
return arr3;
}
int main() {
Array arr1;
arr1.size = 10;
arr1.length = 5;
arr1.A = new int[arr1.size];
arr1.A[0]= 2;
arr1.A[1]= 6;
arr1.A[2]= 10;
arr1.A[3]= 15;
arr1.A[4]= 25;
Array arr2;
arr2.size = 10;
arr2.length = 5;
arr2.A = new int[arr2.size];
arr2.A[0]= 3;
arr2.A[1]= 4;
arr2.A[2]= 7;
arr2.A[3]= 18;
arr2.A[4]= 20;
Array arr3 = merge(arr1, arr2);
display(arr3);
return 0;
}
Your Array arr3 does not allocate any memory for its int *A field. It's natural that it would not work.
Anyway, your implementation of Array is very poor. Don't reimplement arrays unless you have a good reason; use std::vector instead.
If you really need to implement an Array on your own, then learn about encapsulation, make a class with a constructor, and allocate/delete your data (*A) field properly. Remember, using pointers and heap memory without understanding them is a recipe for disaster.
Easy: arr3.A is not initialized. It's a pointer. What does it point to?
Suggestion: learn about dynamic memory allocation.
I'm searching to initialize data of char type like below. but I'm not sure on how to do this
char* data[ ][ ] = {
{"", "index1", "clock1", "Rate1"},
{"", "index2", "clock2", "Rate2"},
{"", "index3", "clock3", "Rate3"},
{"", "index4", "clock4", "Rate4"}
}
so that when I want to assign data of above table to other variables like below
for( int i = 0; i < 6; i++)
{
char k[][];
for(int j = 0; j < 6; j++ )
{
k[i][j] = data[i][j];
}
}
and my expected output is like this
k[i][1] = "index1", k[i][2] = "clock1", k[i][3] = "Rate1"
k[i+1][1] = "index2", k[i+1][2] = "clock2", k[i+1][3] = "Rate2" etc.,
How could I initialize the variable data like above to get the values like mentioned in output?
A couple things to note in the k assignment loop. You are looping 0-6 when the array bounds defined in data are 0-3 (4 elements). You initialized k within your for loop. k will need bounds because it is not being initialized. Remember, arrays in C are of a fixed size. Here is the code I'm referring to:
for( int i = 0; i < 6; i++)
{
char k[][]; /* Re-initialize here? */
for(int j = 0; j < 6; j++ )
{
k[i][j] = data[i][j];
}
}
k will need to be initialized with bounds like this:
char* k[4][4];
Also, your assignment of data is not doing what you think it is. You want to initialize it like this:
char* data[4][4] = {
{{""}, {"index1"}, {"clock1"}, {"Rate1"}},
{{""}, {"index2"}, {"clock2"}, {"Rate2"}},
{{""}, {"index3"}, {"clock3"}, {"Rate3"}},
{{""}, {"index4"}, {"clock4"}, {"Rate4"}}
};
In reality though, this also is not going to be very helpful because, as I said above, arrays are of fixed size. Elements data[0][x] are all single element arrays of char. They will serve no purpose. I think you want to assign different strings to them. Assigning/accessing data[0][x][y] where y is greater than 0 will be undefined behavior. It looks like what you really need here is variable length strings. Since you tagged this question with C++, an easy C++ solution would be to use std::string here. If you really need totally variable length strings in C, you will need to use dynamic memory allocation. For a more simple approach, it would be better to assign data with a fixed string size. Later, if you want to assign different strings, you will want to use strcpy.
Below is a solution for you. I used 20 as the fixed string size. You may want more space.
#include<stdio.h>
int main(int argc, char** argv)
{
char data[4][4][20] = {
{{""}, {"index1"}, {"clock1"}, {"Rate1"}},
{{""}, {"index2"}, {"clock2"}, {"Rate2"}},
{{""}, {"index3"}, {"clock3"}, {"Rate3"}},
{{""}, {"index4"}, {"clock4"}, {"Rate4"}}
};
int i;
int j;
char* k[4][4];
for(i = 0; i < 4; i++)
for(j = 0; j < 4; j++ )
k[i][j] = data[i][j];
for (i = 0; i < 4; ++i)
for(j = 0; j < 4; ++j)
printf("%s\n", k[i][j]);
}
Why does this happen?
u_char macDst[6], macSrc[6], ipType[2]={0x88, 0x92};
u_char header[] = {0x04,0x00,0x20,0x00,...,};
const int len = sizeof(macDst) + sizeof(macSrc) + sizeof(header) + 2;
u_char* pck[len];
int j = 0, length = sizeof(macDst);
for (j; j < length; j++)
{
pck[j] = &macDst[j];
}
length += sizeof(macSrc);
for (j; j < length; j++)
{
pck[j] = &macSrc[j - sizeof(macDst)];
}
pck[j++] = &ipType[0];
pck[j++] = &ipType[1];
length += sizeof(header) + 2;
for (j; j < len; j++)
{
pck[j] = &header[j - sizeof(macDst) - sizeof(macSrc)];
}
u_char testSend[170];
memcpy(testSend, *pck, sizeof(pck));
The var testSend only has macDst values (before initialized), while in the pointer I have all of them. If I copy them one by one, I get a good result:
for (int k = 0; k < 170; k++)
{
testSend[k] = *pck[k];
}
Any idea??
Thanks!!
Edit:
This is a physic problem:
-----ooooooooo------------aaaa----bbbb----
- Null Data
When I make the pointers array I am doing this:
oooooooooaaaabbbb
But when I sent the packet and when I did the memcpy (or memmove) I was saying this: take this pointer and this amount of memory and copy them:
----|oooooooooo----------|----aaaaa----bbbb----
being the amount the sum of the 3 memory places.
I find the code convoluted, and I would never write it this way. Still, the error here:
memcpy(testSend, *pck, sizeof(pck));
You are dereferencing pck - and point to the first element, which is a char*. This is what you copy using your memcpy. On the other hand, your hand-written loop does dereference the pointer before copying it.
Fill the testSend array directly:
u_char *p = testSend;
memcpy(p, macDst, sizeof(macDst)); p += sizeof(macDst);
memcpy(p, macSrc, sizeof(macSrc)); p += sizeof(macSrc);
memcpy(p, ipType, sizeof(ipType); p += sizeof(ipType);
memcpy(p, header, sizeof(header));
I wrote a dynamically allocated 2D array and for some reason it's not working as I intend it to.
I allocated for a 14x5 array to store values in.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, count, count2;
int size, keysize, column;
size = 7; keysize = 10; column = 5;
int row = (size * keysize) / column; // 14
char **arr = (char **)malloc(column * sizeof(char *));
for(i=0; i<row; i++)
arr[i] = (char *)malloc(row * sizeof(char *));
count=0;
count2=0;
for(i=0; i<keysize; i++)
{
for(j=0; j<size; j++)
{
printf("arr[%d][%d]=", count2, count);
arr[count2][count] = 'C';
printf("%c\n", arr[count2][count]);
count++;
if(count == 5)
{
count = 0;
count2++;
}
}
}
return 0;
}
It seems that the program crashes when a value is to be inserted at the location arr[6][0].
Before that it works fine.
I inserted some printf statements to capture this occurring.
I am not sure why it's doing this, the allocation of memory looks fine with me but I am no expert.
Thanks for any help.
change to
char **arr = (char **)malloc(row * sizeof(char *));
for(i=0; i<row; i++)
arr[i] = (char *)malloc(column * sizeof(char));
I notice the question marked with the c++ tag, the clear way to do this in c++ is to use std::vector. So I'm answering this as if it were a C question:
It looks like you haven't allocated enough space here.
column = 5;
char **arr = (char **)malloc(column * sizeof(char *));
This makes space for 5 pointers to rows. Then later on when you are looping:
for(i=0; i<keysize; i++)//note keysize is 10
{
for(j=0; j<size; j++){ // note size is 7
arr[count2][count];
count++;
if(count == 5){
count = 0;
count2++;//gets incremented every time the inner loop runs
}
}
}
Because count2 gets incremented every time the inner loop runs it will get as big as keysize eventually. That means that arr[keysize][0] must be valid, which it isn't because you in effect made arr[5][14]. The first failure is when you call arr[6][0] which accesses past the end of the array and causes your program to crash.
If the intent here is to initialize variables then to fix this you probably want to loop over the same values for dimensions that you used for allocating the memory.
I'm trying to fill an array with numbers 1111 to 8888, with each integer in the number being between 1 and 8 in c++. However, when I run it, it's only outputting large negative numbers indicating an error. I honestly have clue what the error is so it would be appreciated if you could help me out. Thanks!
int fillArray()
{
int arrayPosition;
int guesses[4096];
arrayPosition = 0;
for (int i = 1; i <= 8; i++)
for (int j = 1; j <= 8; j++)
for (int k = 1; k <= 8; k++)
for (int m = 1; m <= 8; m++)
{
guesses[arrayPosition] = ((i * 1000) + (j * 100) + (k *10) + m);
cout << guesses[arrayPosition];
arrayPosition++;
}
return guesses[4096];
}
Your return type is wrong. int fillArray(), but you're trying to return an int[4096] that was declared on the stack... What you're actually doing with return guesses[4096]; is returning the first memory location after your array in memory, which is probably just garbage, hence your issue with large negative numbers.
You can fix it by allocating your array in the heap, and returning a pointer to the start of that array:
int * fillArray()
{
int arrayPosition;
int * guesses = new int[4096];
// other stuff stays the same...
return guesses;
}
However, since your function is called fillArray, it would make more sense to pass in an array and fill it rather than creating the array in the function. (If you wanted to do that, might call it something like make_1_to_8_array instead, to make it more clear that you're constructing something that will need to be deleted later.) Giving an int* as the first argument would allow you to pass in the base address of your array that you want filled:
void fillArray(int * guesses)
{
int arrayPosition;
// other stuff stays the same...
}
Or, if you want to verify that the you're using an array of the exact size:
void fillArray(int (&guesses)[4096])
{
int arrayPosition;
// other stuff stays the same...
}
Note that the function now returns void since you just update the array that was passed in, and you don't need to return anything new.
Your for-loops look correct, but your array handling is off, as is highlighted by other answers.
It is more usual in C++ to use std::vector and to pass this in by reference as an argument. This saves you having to handle memory allocations and deallocations. Here's an example, including the output in the for-loops:
#include <iostream>
#include <vector>
int fillArray(std::vector<int>& guesses)
{
for (int i = 1; i <= 8; i++)
for (int j = 1; j <= 8; j++)
for (int k = 1; k <= 8; k++)
for (int m = 1; m <= 8; m++)
{
guesses.push_back((i * 1000) + (j * 100) + (k * 10) + m);
std::cout << guesses.back() << std::endl;
}
return guesses.back();
}
int main()
{
std::vector<int> guesses;
std::cout << fillArray(guesses) << std::endl;
}
You are creating your array locally then attempting to return it. If you try printing (to debug) out the result of your array prior to returning, you will see it is ok. However, once you return, the array is no linger valid. Try passing in an array into your function instead.