I am struggling to find the answer to this:
#define BUFLEN 8
unsigned short randombuffer[BUFLEN];
memset(randombuffer, 200 , BUFLEN );
printf("%u", randombuffer[0]);
I am getting the answer as 51400 although I was expecting 200.
After debugging I found out that the randombuffer is filled with 0xC8 for the first 8 entries. Hence 0xC8C8 is 51400. I was however expecting 0x00C8 for each index in the array.
What am I doing wrong?
What you are doing wrong is not reading the spec of memset. memset sets each byte to the specified value. Your buffer has most likely 8 entries of two bytes each. Since you passed 8 to memset, both bytes of the first four entries are changed, the rest isn't touched. That's who memset works.
memset fills bytes, but it looks like you want to fill words. I don't know if there's a memset-like function built in for this, so you might have to do repeated memset/memcpy instead. Note that if you feel comfortable writing inline assembler you could probably do this pretty efficiently yourself in machine code - although a tight loop using pointers in C is probably close to as fast.
The size calculation in the memset call is not correct. It should be:
memset(randombuffer, 200 , BUFLEN * sizeof(*randombuffer) );
because individual elements in randombuffer are two bytes in your case and the third parameter in memset takes the amount of bytes of the object, so you have to pass the number of the elements in the object times their size in bytes.
The values in the elements will still remain 0xC8C8, because memset set a value per byte not per element.
To print them out correctly, use the correct specifier for short:
printf("%hu", randombuffer[0]);
or
printf("%hx", randombuffer[0]);
Related
This might seem silly, but, I am using libaio ( not posix aio), I am able to write something into the file, but I am also writing extra stuff into the file.
I read about the alignment requirement and the data type of the buffer field of iocb.
Here is the code sample ( only relevant sections of use, for representation )
aio_context_t someContext;
struct iocb somecb;
struct io_event someevents[1];
struct iocb *somecbs[1];
somefd = open("/tmp/someFile", O_RDWR | O_CREAT);
char someBuffer[4096];
... // error checks
someContext = 0; // this is necessary
io_setup(32, &someContext ); // no error checks pasted here
strcpy(someBuffer, "hello stack overflow");
memset(&somecb, 0, sizeof(somecb));
somecb.aio_fildes = somefd ;
somecb.aio_lio_opcode = IOCB_CMD_PWRITE;
somecb.aio_buf = (uint64_t)someBuffer;
somecb.aio_offset = 0;
somecb.aio_nbytes = 100; // // //
// I am avoiding the memeaign and sysconf get page part in sample paste
somecbs[0] = &somecb; // address of the solid struct, avoiding heap
// avoiding error checks for this sample listing
io_submit(someContext, 1, somecbs);
// not checking for events count or errors
io_getevents(someContext, 1, 1, someevents, NULL);
The Output:
This code does create the file, and does write the intended string
hello stack overflow into the file /tmp/someFile.
The problem:
The file /tmp/someFile also contains after the intended string, in series,
#^#^#^#^#^#^#^#^#^ and some sections from the file itself ( code section), can say garbage.
I am certain to an extent that this is some pointer gone wrong in the data field, but cannot crack this.
How to use aio ( not posix) to write exactly and only 'hello world' into a file?
I am aware that aio calls might be not supported on all file systems as of now. The one I am running against does support.
Edit - If you want the starter pack for this attempt , you can get from here.
http://www.fsl.cs.sunysb.edu/~vass/linux-aio.txt
Edit 2 : Carelessness, I was setting up more number of bytes to write to within the file, and the code was honoring it. Put simply, to write 'hw' exactly one needed no more than 2 bytes in the bytes field of iocb.
There's a few things going on here. First up, the alignment requirement that you mentioned is either 512 bytes or 4096 bytes, depending on your underlying device. Try 512 bytes to start. It applies to:
The offset that you're writing in the file must be a multiple of 512 bytes. It can be 0, 512, 1024, etc. You can write at offset 0 like you're doing here, but you can't write at offset 100.
The length of data that you're writing to the file must be a multiple of 512 bytes. Again, you can write 512 bytes, 1024 bytes, or 2048 bytes, and so on - any multiple of 512. You can't write 100 bytes like you're trying to do here.
The address of the memory that contains the data you're writing must be a multiple of 512. (I typically use 4096, to be safe.) Here, you'll need to be able to do someBuffer % 512 and get 0. (With the code the way it is, it most likely won't be.)
In my experience, failing to meet any of the above requirements doesn't actually give you an error back! Instead, it'll complete the I/O request using normal, regular old blocking I/O.
Unaligned I/O: If you really, really need to write a smaller amount of data or write at an unaligned offset, then things get tricky even above and beyond the io_submit interface. You'll need to do an aligned read to cover the range of data that you need to write, then modify the data in memory and write the aligned region back to disk.
For example, say you wanted to modify offset 768 through 1023 on the disk. You'd need to read 512 bytes at offset 512 into a buffer. Then, memcpy() the 256 bytes you wanted to write 256 bytes into that buffer. Finally, you issue a write of the 512 byte buffer at offset 512.
Uninitialized Data: As others have pointed out, you haven't fully initialized the buffer that you're writing. Use memset() to initialize it to zero to avoid writing junk.
Allocating an Aligned Pointer: To meet the pointer requirements for the data buffer, you'll need to use posix_memalign(). For example, to allocate 4096 bytes with a 512 byte alignment restriction: posix_memalign(&ptr, 512, 4096);
Lastly, consider whether you need to do this at all. Even in the best of cases, io_submit still "blocks", albeit at the 10 to 100 microsecond level. Normal blocking I/O with pread and pwrite offers a great many benefits to your application. And, if it becomes onerous, you can relegate it to another thread. If you've got a latency-sensitive app, you'll need to do io_submit in another thread anyway!
Would running this code occupy about 4_000_000 bytes of memory?
my uint32 #array;
#array[1_000_000] = 1;
If you assign element 1_000_000 and each element is 4 bytes, that would be 4_000_004 bytes of memory. So strictly speaking, the answer is "No" :-)
But less pedantically: native arrays are guaranteed to be laid out consecutively in memory, so such an assignment would at least allocate a single block of 4 x 1_000_001 = 4_000_004 bytes of memory. As Christoph stated in his comment, if you want to make sure it is all it will ever allocate, you need to make it a shaped native array. You will get upper bounds checks as a bonus as well.
How can I get the Length of an array with a specific index for example if I have an array like this
TYPE T_PERSON = PACKED RECORD
Example : STRING[40];
Example2 : STRING[10];
Example3 : STRING[5];
END;
example: ARRAY [1..30] OF T_PERSON
and I want to know the Length of example[28] respectively example[x].
Can I get it with LENGTH() or is there another solution?
If it is an array and you want the number of elements:
high(example)-low(example)+1;
Afaik with Free Pascal and Delphi 4+ length might also work, but don't pin me on that.
If you need the size in bytes, Abelisto is correct and sizeof() is what you want, and it also works on parts of the record (e.g. sizeof(example.example)).
The sum might not add up though if you are not PACKED due to alignment bytes.
Yes, you can also get it with Length function.
function Length(A: DynArrayType):Integer;
Every cell/element of your 'example' array has SizeOf(T_PERSON). This is the number of bytes.
As it stands, SizeOf(T_PERSON) is 58 bytes.
What I cannot explain is why it is 58 bytes and not 55 bytes (as I would expect it for non packed record) or even 56 bytes (for packed record aligned at 4-byte boundary).
Maybe someone else can shed some light on that.
I have to allocate a dynamic array and i know how many columns there will be on the array but i don't know how many rows, all i have is a number on a .txt file. I have tried the following code but i am not sure it will work:
int x = (int)fgetc(file)-48;
Since the ascii value of 0 is 48, i assumned that i needed to cast the character read from the file in order to be able to use it as my rows number.
I assume i should be able to allocate the array the 2D array as it follows:
m = (int **)malloc(x*sizeof(int*));
for (i=0;i<x;i++)
{
m[i] = (int*)malloc(10*sizeof(int));
}
Am i correct? Any help will be highly apretiated.
You can design a list and dynamically insert your rows.
First off fgetc() returns an integer, so casting it as an int will do nothing. Second you're only reading in one integer at a time with fgetc() so you will have a 1 digit number in x.
Your array allocation looks correct, but you can also allocate the columns as an array of int * on the stack and then allocate the rows dynamically as m[i] = (int*)malloc(x*sizeof(int)); from i = 0->9
Do I understand correctly that your file looks like
327 // number of lines
1 2 3 // line 1
33 44 55 // line 2
... repeats until 327 lines have been printed, all with 3 elements? Note that the line breaks would be optional and could be any whitespace.
The canonical way to read a number from text in C is using scanf. scanf uses, like printf, a weird looking format string as the fist parameter. Each basic type has a letter associated with it, for integers it's d or, more intuitively, i. These letters are prefixed with a %. So to read an integer, you would write scanf("%d", &lines); if lines is an int holding the number of lines. (Do rather not use x, for readability).
The way you allocate your array is correct (provided x holds the number of lines and 10 is the known line length). One style issue is that the 10 should be #defined as a macro so that you can use e.g. malloc(LINE_LEN*sizeof(int)). That helps later when that number should ever change and you have (in a real world program) scattered references to m over several source files.
If this is just a little program and the array isnt't inordinately large and does not need to live longer than the function call (which, in the case of main(), may be long enough in any case), the easiest would be to use a variable size array in C; provided you use a modestly modern compiler:
#define LINE_LEN 10
int lineCount;
scanf("%d", &lineCount);
int m[lineCount][LINE_LEN];
// fill from file
If you compile with gcc you'll probably need to specify "-std=c99" as a command line option for that.
Note: There are posts similar to this for C++ only, I didn't find any useful post in regards to C.
I want to set the array of elements with the same value. Of course, this can be achieved simply using a for loop.
But, that consumes a lot of time. Because, in my algorithm this setting array with same value takes place many number of times. Is there any simple way to achieve this in C.
Use a for loop. Any decent compiler will optimize this as much as possible.
It is a near certainty that you wouldn't be able to improve substantially on the speed of your for loop. There is no magic way to set a value into multiple memory locations faster than it takes to store that value into these multiple memory locations. Regardless of whether you use the for loop or not, all the locations must be written to, which takes most of the time.
There is of course the void * memset ( void * ptr, int value, size_t num ); for values composed of identical bytes1, but under the hood it has a loop. Perhaps the implementation could be very smart about using that loop, but so can the optimizing compiler.
1 Although memset takes an int, it converts it to unsigned char before setting it into the memory region.
As suggested by other users, use memset if you want to initiate your array with 0 values, but don't do it if the values are not that simple.
For more complicated values, you can have a constant copy of your initial values and copy them later with memcpy:
float original_values[100]; // don't modify these values
original_values[0] = 1.2f;
original_values[1] = 10.9f;
...
float working_values[100]; // work with these values
memcpy(working_values, original_values, 100 * sizeof(float));
// do your task
working_values[0] *= working_values[1];
...
You can use memset() . It fills no of bytes you want to fill with same byte value.Here
you can read man page.
You can use memset() function
Example:
memset(<array-name>,<initialization-value>,<len>);
You can easily memset an array to 0.
If you want a different value, it all depends on the type used.
For char* arrays you can memset them to any value, since char is almost always one byte long.
For an array of structures, if all fields of a structure are to be initialized with 0 or NULL, you can memset it with 0.
You can not memset an array or array of structures to any value other than 0, because memset operates on single bytes. So if you memset an int[] with 1, you will not have an array of 1's.
To initialize an array of structures with a custom value, just fill one structure with the desired data and do an assignment it in a for. The compiler should do it relatively efficiently for you.
If you are talking about initialization see this question. If you want to set the values at a later time then use memset
Well you can only set your values to zero for a particular array. Here is an example
int arr[5]={0};