I am working with sending data to and from a client/server application. I have created my own header scheme. This is the flow I am in question about:
char *data = returnmydata();
int one = 1;
int two = 2;
int three = 3;
So what happens is I have a char buffer that contains all my data. But I need to append to the front of this data my one, two, and three integers which is used to let the other side know how to handle the data.
Instead of allocating enough at the start for the 3 header items, is it possible to reallocate an addition 12 bytes and move the start of the data to data+12?
I currently just memcpy the 3 integers at the start then offset the data +12. However I think my code would be better if I could just pass a struct that contains the 3 ints and a pointer to the data. Then I can use this function to create the full data buffer with the headers in it.
Another option is to alloc another buffer memcpy the 3 integers to the front, and then memcpy the data to the new buffer. However I would like to keep memory usage low.
Use functions realloc and memmove.
If the size of the initially allocated buffer is equal to some value N then you can write
char *tmp = realloc( data, N + 12 );
if ( tmp != NULL )
{
data = tmp;
memmove( data + 12, data, N );
// then you can insert some values in the first 12 bytes of the allocated buffer
}
i am new to coding and am having a problem with the following.
I am required to read from a text file, each row will contain:
command arg1 arg2 arg3...
command arg1 arg2
command
command arg1 arg2 ... arg9
etc
What i am trying to do is read this entire file into a 2D string array called array using malloc. This way if i were to do:
array[0][0] i would access command arg1 arg2 arg3
array[1][0] i would access command arg1 arg2
and so on.
I also know there is a max of 100 rows and 256 characters per line. Below is how i attempted to declare my malloc however when trying to allocate strings to the 2d array, it only allocated single characters.
I dont quite understand how to do this, detailed explanation would be greatly appreciated
int row = 100;
int col = 256;
int **array;
array = (int**)malloc(row*sizeof(array));
if(!array){
perror("Error occured allocating memory");
exit(-1);
}
for(int i = 0; i<row;i++){
array[i] = (int*)malloc(col*sizeof(array));
}
If I got it right, you need to set up a two dimensional array of char * instead of int.
That is, you address the correct row by dereferencing once (array[the_ith_row]), and then address the correct element(command, arg1, arg2, ...) by another dereference (array[the_ith_row][the_jth_col]).
Notice: strings like "arg1" and "command" are treated as "array of chars" therefore you need to store a char * in order to access them. int could only store one char(with some extra space consumption), therefore won't work here.
So, the correct one should look like:
#include <string.h>
int row = 100;
int col = 256;
char ***array;
array = (char ***)malloc(row * sizeof(char **));
if (!array) {
perror("Error occured allocating memory");
exit(-1);
}
for (int i = 0; i < row; i++) {
array[i] = (char **)malloc(col * sizeof(char *));
}
// Do some example assignments
for (int j = 0; j < col; j++) {
array[i][j] = strcpy((char *)malloc(100), "test_string");
}
//therefore printf("%s", array[0][0]); will print test_string"
UPDATE: I missed some * here..
You are allocating using sizeof(array) which is not the correct unit of allocation that you want.
It looks like what you want are two different kinds of memory allocations or objects.
The first is an array of pointers to character strings since the file data is a series of character strings.
The second kind of memory allocation is for the memory to hold the actual character string.
The first kind of memory allocation, to an array of pointers to character strings would be:
char **pArray = malloc (100 * sizeof(char *)); // allocate the array of character string pointers
The second kind of memory allocation, to a character string which is an array of characters would be:
char *pString = malloc ((256 + 1) * sizeof(char)); // allocate a character array for up to 256 characters
The 256 + 1 is needed in order to allocate space for 256 characters plus one more for the end of string character.
So to allocate the entire needed space, you would do the following:
int iIndex;
int nMax = 100;
char **pArray = malloc (nMax, sizeof(char *)); // allocate array of rows
for (iIndex = 0; iIndex < nMax; iIndex++) {
pArray[iIndex] = malloc ((256 + 1) * sizeof (char)); // allocate a row
}
// now use the pArray to read in the lines of text from the file.
// for the first line, pArray[0], second pArray[1], etc.
Using realloc()
A question posed is using the realloc() function to adjust the size of the allocated memory.
For the second kind of memory, memory for the actual character string, the main thing is to use realloc() as normal to expand or shrink the amount of memory. However if memory is reduced, you need to consider if the text string was truncated and a new end of string terminator is provided to ensure the text string is properly terminated with and end of string indicator.
// modify size of a text string memory area for text string in pArray[i]
// memory area. use a temporary and test that realloc() worked before
// changing the pointer value in pArray[] element.
char *p = realloc (pArray[i], (nSize + 1) * sizeof (char));
if (p != NULL) {
pArray[i] = p; // valid realloc() so replace our pointer.
pArray[i][nSize] = 0; // ensure zero terminator for string
}
If you ensure that when the memory area for pArray] is set to NULL after allocating the array, you can just use the realloc() function as above without first using malloc() since if the pointer in the argument to realloc() is NULL then realloc() will just do a malloc() for the memory.
For the first kind of memory, you will need to consider freeing any memory whose pointers may be destroyed when the allocated array is shortened. This means that you will need to do a bit more management and keeping management data about the allocated memory area. If you can guarantee that you will only be increasing the size of the array and never shortening it then you don't need to do any management and you can just use the same approach as provided for the second kind of memory above.
However if the memory allocated for the first kind of memory will need to be smaller as well as larger, you need to have some idea as to the size of the memory area allocated. Probably the easiest would be to have a simple struct that would provide both a pointer to the array allocated as well as the max count of items the array can hold.
typedef struct {
size_t nCount;
char **pArray;
} ArrayObj;
Warning: the following code has not been tested or even compiled. Also note that this only works for if the memory allocation will be increased.
Then you would wrap the realloc() function within a management function. This version of the function only handles if realloc() is always to expand the array. If making it smaller you will need to handle that case in this function.
ArrayObj ArrayObjRealloc (ArrayObj obj, size_t nNewCount)
{
// make the management a bit easier by just adding one to the count
// to determine how much memory to allocate.
char **pNew = realloc (obj.pArray, (nNewCount + 1) * sizeof (char *));
if (pNew != NULL) {
size_t ix;
// realloc() worked and provided a valid pointer to the new area.
// update the management information we are going to return.
// set the new space to NULL to have it in an initial and known state.
// initializing the new space to NULL will allow for knowing which array
// elements have a valid pointer and which don't.
obj.pArray = pNew;
for (ix = nNewCount; ix >= obj.nCount; ix--) {
obj.pArray[ix] = NULL;
}
obj.nCount = nNewCount;
}
return obj;
}
and use this function something like
AnyObj obj = {0, NULL};
// allocate for the first time
obj = ArrayObjRealloc (obj, 100);
// do stuff with the array allocated
strcpy (obj.pArray[i], "some text");
// make the array larger
obj = ArrayObjRealloc (obj, 150);
I have open a file and I know how to read the number of bytes that I want for it but now I want to save that bytes into a specific adress from memory and i dont know how I can do that.
The following code is what i have:
void fileSaver(char * n []){
int fil;
int bytes;
char * space = malloc(100);
fil= open("file",O_RDONLY);
bytes=read(fil,space,4);
printf("%d\n",bytes );
printf("%s\n",space );
}
the n that I use as parameter for the function is the number of bytes that I want to read
I more or less have an idea, but I'm not sure if I've even got the right idea and I was hoping maybe I was just missing something obvious. Basically, I have and array of strings (C strings, so basically an array of pointers to character arrays) like so:
char **words;
Which I don't know how many words I'll have in the end. As I parse the string, I want to be able to resize the array, add a pointer to the word, and move on to the next word then repeat.
The only way I can think of is to maybe start with a reasonable number and realloc every time I hit the end of the array, but I'm not entirely sure that works. Like I want to be able to access words[0], words[1], etc. If I had char **words[10] and called
realloc(words, n+4) //assuming this is correct since pointers are 4 bytes
once I hit the end of the array, if I did words[11] = new word, is that even valid?
Keep track of your array size:
size_t arr_size = 10;
And give it an initial chunk of memory:
char **words = malloc( arr_size * sizeof(char*) );
Once you have filled all positions, you may want to double the array size:
size_t tailIdx = 0;
while( ... ) {
if( tailIdx >= arr_size ) {
char **newWords;
arr_size *= 2;
newWords = realloc(words, arr_size * sizeof(char*) );
if( newWords == NULL ) { some_error() };
words = newWords;
}
words[tailIdx++] = get_next_word();
}
...
free(words);
That approach is fine ,although you may want to do realloc(words, n * 2) instead. calling realloc and malloc is expensive so you want to have to reallocate as little as possible and this means you can go for longer without reallocating (and possibly copying data). This is how most buffers are implemented to amortize allocation and copy costs. So just double the size of your buffer every time you run out of space.
You are probably going to want to allocate multiple blocks of memory. One for words, which will contain the array of pointers. And then another block for each word, which will be pointed to by elements in the words array.
Adding elements then involves realloc()ing the words array and then allocating new memory blocks for each new word.
Be careful how you write your clean up code. You'll need to be sure to free up all those blocks.
I am trying to store a string data file into a multi-dimensional array using C.My sample data looks as below.I am thinking to use below char declaration for storing my data.Please kindly advise me if there is any other method.
char *array[6][10];
53,v42,p11,51097,310780,ok
56,v45,p11,260,1925,ok
68,v42,p11,51282,278770,ok
77,v50,p11,46903,281485,ok
82,v46,p12,475,2600,ok
84,v48,p12,433,3395,ok
96,v49,p14,212,1545,ok
163,v50,p20,373819,1006375,ok
204,v50,p26,36917,117195,ok
241,v70,p33,21777,91360,ok
Looks fine, if you want it to be strings.
What I suggest is to not allocate a string for every single field. Instead, read a line from the file, allocate a single string for it, tokenise out the commas, and store the pointers in your 2D array.
Or indeed, if your data file fits easily into memory, there's no reason not to read the entire thing and tokenise. Effectively, you just use your array as an index into the buffer.
There are many other ways to do it; some will depend on whether you've learned about structures yet.
One point to note: C uses 'row-major' ordering for arrays, so most programmers would write char *array[10][6]; for 10 rows of 6 columns each.
You could decide that instead of using char *, you allow, say, 10 characters per string, and use:
char array[10][6][10];
This would fit the data shown (with a little room to spare; the second 10 could be as small as 8 for the data shown). It would require a lot less dynamic memory management.
Alternatively, you could define a structure that represents a line:
struct csv_line
{
int col1;
char col2[4];
char col3[4];
int col4;
int col5;
char col6[4]; // Correct length uncertain...
};
And then have a 1-dimensional array of these:
struct csv_line array[10];
This is more or less how I'd do it. Note that the structure uses 24 bytes per line compared with 48 per line in char array[10][6][8];, and compared with 48 bytes for pointers plus the actual strings and storage overhead for the char * versions on a 64-bit machine. The total storage for the char pointer version could easily be 144 bytes per row on a 64-bit machine.
Clearly, this analysis of size assumes that you have separate allocations for each string. If you read each line of data into a separately allocated line and then store pointers to the parts of the line, the storage overhead is (dramatically) reduced. A lot will depend on how you are going to use the data. If you're going to treat the numeric-looking fields as numbers, then I'd use the structure; it will save on data conversions later.
I hope this sample program will help you to address your issue. I used structure and sscanf. This is the nice way to address this issue.
#include <stdio.h>
struct data
{
char date[100];
char state[100];
char profit[100];
char revenue[100];
};
int main()
{
char line[4096] = {'\0'};
char t1[100], t2[100], t3[100], t4[100];
struct data d[2];
int i = 0;
while(fgets(line, 4096, stdin) != NULL) {
sscanf(line, "%[^','],%[^','],%[^','],%s", &t1, &t2, &t3, &t4);
strcpy(d[i].date, t1);
strcpy(d[i].state, t2);
strcpy(d[i].profit, t3);
strcpy(d[i++].revenue, t4);
}
i = 0;
while(i<2){
printf("%s %s %s %s\n", d[i].date, d[i].state, d[i].profit, d[i].revenue);
i++;
}
}
$> a./exe < file
$> cat file
12/2/2012,TN,1200,14000
12/3/2012,KA,2333554,424