I am attempting to write C functions with these two prototypes:
int extract_little (char* str, int ofset, int n);
int extract_big(char* str, int ofset, int n);
Now the general idea is I need to return a n byte integer in both formats starting from address str + ofset. P.S. Ofset doesn't do anything yet, I plan on (trying) to shuffle the memory via an offset once I figure out the little endian, for the big.
I'v trying to get it to output like this; for little endian, based off of i=0xf261a3bf;,
0xbf 0xa3 0x61 0xf2
int main()
{
int i = 0xf261a3bf;
int ofset = 1; // This isn't actually doing anything yet
int z;
for (z = 0; z < sizeof(i); z++){
printf("%x\n",extract_little((char *)&i,ofset, sizeof(i)));
}
return 0;
}
int extract_little(char *str,int offs, int n) {
int x;
for (x = 0; x < n; x++){
return str[x];
}
}
I'm not sure what else to try. I figured out the hard way that even thought I put it in a for loop I still can't return more than 1 value from the return.
Thanks!
unsigned long extract_little(const void *p, size_t offset, unsigned char n) {
unsigned long ret = 0;
for(size_t i = offset + n - 1; i >= offset; i--)
ret = (ret<<8) + ((char *)p)[i];
return ret;
}
unsigned long extract_big(const void *p, size_t offset, unsigned char n) {
unsigned long ret = 0;
for(size_t i = offset; i < (offset + n); i++)
ret = (ret<<8) + ((char *)p)[i];
return ret;
}
int main()
{
int i = 0xf261a3bf;
printf("%x\n", extract_little(&i, 0, sizeof(i)));
return 0;
}
Works (of course) only with n´s which are sizeof(unigned long) maximal.
And can be speed-improved, probably (depending on the compiler optimization).
With respect to your code: return does what it says, it returns from the function. The loop is never run for more than the first element.
With respect to the problem: Check out htonl and ntolh, except for exercise.
Related
I wrote a code in c in order to solve Project Euler Problem 45 (https://projecteuler.net/problem=45). I keep getting segmentation fault error 139. I am sure it is not about trying to access a memory location that I do not have permission for.
My guessing is , the problem is related to sizes of my arrays. I looked up the answer and it is some 10 digit number. To get that ten digit number the size of the array "triangle" has to be something between one million and two million. But when I make the array that big i get the error. I don't get the error in the code below since size of that array is 500 000 (but of course that is not enough).
I use ubuntu 16.04 and Geany.
If you need more information please ask. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
unsigned long pentagonalgenerator(int n);
unsigned long trianglegenerator(int n);
unsigned long hexagonalgenerator(int n);
_Bool search_function(unsigned int to_be_looked_for , unsigned long array[] , int sizeofarray);
int main(void)
{
unsigned long pentagon[28000] = {0};
int sizeofpentagon = 28000;
unsigned long hexagon[100000] = {0};
int sizeofhexagon = 100000;
unsigned long triangle[500000] = {0};
int sizeoftriangle = 500000;
int counter;
for(counter = 0 ; counter < sizeofpentagon ; counter++)
{
pentagon[counter] = pentagonalgenerator(counter + 2);
}
for(counter = 0 ; counter < sizeofhexagon ; counter++)
{
hexagon[counter] = hexagonalgenerator(counter + 2);
}
for(counter = 0 ; counter < sizeoftriangle ; counter++)
{
triangle[counter] = trianglegenerator(counter + 2);
}
printf("%lu \n%lu \n%lu \n", hexagon[sizeofhexagon - 1] , pentagon[sizeofpentagon - 1] , triangle[sizeoftriangle - 1]);
for(counter = 0 ; counter < sizeofhexagon ; counter++)
{
if(search_function(hexagon[counter] , pentagon , sizeofpentagon))
{
if(search_function(hexagon[counter] , triangle , sizeoftriangle) && hexagon[counter] != 40755)
{
printf("%lu", hexagon[counter]);
return 0;
}
}
}
return 1;
}
_Bool search_function(unsigned int to_be_looked_for , unsigned long array[] , int sizeofarray)
{
int left = 0, right = sizeofarray - 1 , middle = 0;
while(left <= right)
{
middle = (left + right) / 2;
if(to_be_looked_for == array[middle]) return 1;
else if(to_be_looked_for < array[middle]) right = middle - 1;
else if(to_be_looked_for > array[middle]) left = middle + 1;
}
return 0;
}
unsigned long pentagonalgenerator(int n)
{
unsigned int return_value = 0;
return_value = (n*(3*n - 1)) / 2;
return return_value;
}
unsigned long hexagonalgenerator(int n)
{
unsigned int return_value = 0;
return_value = n*(2*n - 1);
return return_value;
}
unsigned long trianglegenerator(int n)
{
unsigned int return_value = 0;
return_value = (n*(n + 1)) / 2;
return return_value;
}
That's a lot of memory for the stack. Instead of this
unsigned long pentagon[28000] = {0};
int sizeofpentagon = 28000;
unsigned long hexagon[100000] = {0};
int sizeofhexagon = 100000;
unsigned long triangle[500000] = {0};
int sizeoftriangle = 500000;
Try this:
unsigned long *pentagon = calloc(28000*sizeof(unsigned long));
int sizeofpentagon = 28000;
unsigned long *hexagon = calloc(100000 * sizeof(unsigned long));
int sizeofhexagon = 100000;
unsigned long *triangle = calloc(500000 * sizeof(unsigned long));
int sizeoftriangle = 500000;
You have very large arrays defined as local variables in the stack. You are getting a stack overflow because of that. Arrays pentagon hexagon triangle are very large.
These need to be moved to the global space or they should be dynamically allocated. For your use case, it is easier to move the arrays to global.
unsigned long pentagon[28000] = {0};
unsigned long hexagon[100000] = {0};
unsigned long triangle[500000] = {0};
int main(void)
{
int sizeofpentagon = 28000;
int sizeofhexagon = 100000;
int sizeoftriangle = 500000;
....
The maximum size for automatic variables is an implementation dependent detail. BUT major implementation have options to set it.
For example, if you are using gcc or clang, automatic variables are stored in the stack, and the stack size is controlled at link time by the option --stack <size>. The default size is 2Mb and your arrays require 628000 unsigned long so at least 5Mb.
Provided you have more standard requirements in other places of this code, I would try a 8Mb stack:
cc myprog.c -Wl,--stack -Wl,0x800000 -o myprog
(-Wl, is used to pass the argument to the linker phase of the build).
This avoids to reformat your code (for examble using allocated arrays) to only solve a compilation problem.
I am trying to make a software that takes a txt file and xor every 4 byte with a pre-defined number.
I am doing this mapping the file in memory and opening chunks of the file with MapViewOfFile of size n.
The algorithm I'm attaching works well for txt files of less than 250 kb. But for file > 250kb it only xor some parts of the file and I cannot understand why and how to fix this.
Can someone help me?
#include "stdafx.h"
#include "Windows.h"
#include <stdio.h>
#include <stdint.h>
#include <iso646.h>
#include <math.h>
unsigned int strToUl(char *s)
{
int size = 4;
unsigned int ul = 0;
memcpy(&ul, (unsigned int *)s, size);
return ul;
}
char *ulToStr(unsigned int *ul)
{
int size = 4;
char *tch = (char *)calloc(size, sizeof(char *));
memcpy(tch, (char *)ul, size);
return tch;
}
unsigned int uixor(unsigned int n, unsigned int seed)
{
srand(seed);
unsigned int mask = rand();
char ch[5] = { 0 };
strcpy_s(ch, 5, ulToStr(&n));
for (int j = 0; j < 5; j++)
{
ch[j] = ch[j] ^ mask;
}
return strToUl(ch);
}
BOOL mapWriteChunk(PHANDLE phFile, DWORD dwFileSize, int start, int buffsize, uint32_t xork)
{
DWORD offset = start;// / 4;// / sizeof(DWORD);
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
DWORD dwSysGran = SysInfo.dwAllocationGranularity;
DWORD dwFileMapStart = (offset/dwSysGran) * dwSysGran;
DWORD dwMapViewSize = (offset % dwSysGran) + buffsize;
DWORD dwFileMapSize = offset + buffsize;
unsigned int *ulMVBuffer = (unsigned int *)MapViewOfFile(*phFile, FILE_MAP_ALL_ACCESS, 0, dwFileMapStart, 0);
if (ulMVBuffer == NULL)
{
printf("ulMVBuffer = NULL\n");
}
int iViewDelta = offset - dwFileMapStart;
for (int i = 0; i < buffsize; i++)
{
unsigned int *u = (unsigned int *)ulMVBuffer + (iViewDelta + i);
unsigned int u1 = *u;
unsigned int u2 = uixor(u1, xork);
*u = u2;
printf("write on %d -> ", iViewDelta);
}
UnmapViewOfFile(ulMVBuffer);
return TRUE;
}
int main()
{
char name[] = "test.txt";
OFSTRUCT tOfStrIn;
tOfStrIn.cBytes = sizeof tOfStrIn;
HANDLE hFile = (HANDLE)OpenFile(name, &tOfStrIn, OF_READWRITE);
DWORD dwFileSize = GetFileSize(hFile, NULL);
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize, NULL);
if (hFileMap == NULL)
{
printf("hFileMap = NULL\n");
}
int pos = 0;
int chunk = 4;
int bSize = dwFileSize / sizeof(DWORD);
int rseed = 10;
for (pos = 0; pos < bSize; pos+=chunk)
{
mapWriteChunk(&hFileMap, dwFileSize, pos, chunk, rseed);
}
CloseHandle(hFile);
CloseHandle(hFileMap);
system("PAUSE");
return 0;
}
Ok, I figured out the problem and I'm writing here so anyone who have the same problem, know what's wrong.
Talk is cheap, I show you the code (and then I'll explain):
char *ulMVBuffer = (char *)MapViewOfFile(phFile, FILE_MAP_ALL_ACCESS, 0, dwFileMapStart, 0);
if (ulMVBuffer == NULL)
{
printf("ulMVBuffer = NULL\n");
}
int iViewDelta = offset - dwFileMapStart;
unsigned int mask = myrand(xork);
for(int i = 0; i < buffsize; i++)
{
unsigned int c = ulMVBuffer[iViewDelta + i] ^ mask;
ulMVBuffer[iViewDelta + i] = c;
}
So you have to map the memory using a char pointer and then, when you use the XOR operator like that:
unsigned int c = ulMVBuffer[iViewDelta + i] ^ mask;
You obtain the XOR to be applied to a group of 4 bytes and not only on 1 byte, because - as far as I understood playing around - the XOR between a char (1 byte) and a unsigned int (4 bytes) forces the operator to pick 3 more bytes from the memory and use it for the bitwise operation.
This wasn't working using a pointer to unsigned int because, I guess, it stored the bytes from the memory in a different fashion (maybe OS or machine dependent?) and so you were able to XOR only 1 byte every 4 and not groups of 4 bytes all together.
If anyone has a better understanding to this or wants to add more to this solution, I will be more than happy to read it!
I want to make a function that converts unsigned char to unsigned int and store it into an array. However, this ends up with an error that says
passing argument 1 of 'sprintf' from incompatible pointer type.
int main(void) {
unsigned char key[16] = "1234567812345678";
phex(key, 16); //store into an array here
}
uint64_t* phex(unsigned char* string, long len)
{
uint64_t hex[len];
int count = 0;
for(int i = 0; i < len; ++i) {
count = i * 2;
sprintf(hex + count, "%.2x", string[i]);
}
for(int i = 0; i < 32; i++)
printf(hex[i]);
return hex;
}
As comments have already said, you have problems in your code...
First of all sprintf function does totally opposite thing of what you want/expect it to do. Next, you create a local variable in your function, and return pointer to it.. As soon as function exits, pointer is invalid. Third problem I see is that you never assign return value to anything...
Proposition on how to fix your code:
unsigned* phex(unsigned char* string, long len);
int main(void) {
int i;
unsigned char key[16] = "1234567812345678";
unsigned* ints = phex(key,16); //store into an array here
for(i = 0; i < 16; i++)
printf("%d ", ints[i]);
//never forget to deallocate memory
free(ints);
return 0;
}
unsigned* phex(unsigned char* string, long len)
{
int i;
//allocate memory for your array
unsigned* hex = (unsigned*)malloc(sizeof(unsigned) * len);
for(i = 0; i < len; ++i) {
//do char to int conversion on every element of char array
hex[i] = string[i] - '0';
}
//return integer array
return hex;
}
I'm learning how numbers are represented in memory. I want to know how to print the actual representation (binary or hexadecimal) in memory of some int and float variables.
I'd like to see what happens with that numbers when adding or subtracting it causes overflow, for example.
How can I access memory and print it?
You would need to assign a pointer to the variable in question to a char *, and treat it as an array of bytes of length sizeof(variable). Then you can print each byte in hex using the %X format specifier to printf.
You can define a function like this:
void print_bytes(void *ptr, int size)
{
unsigned char *p = ptr;
int i;
for (i=0; i<size; i++) {
printf("%02hhX ", p[i]);
}
printf("\n");
}
And call it like this:
int x = 123456;
double y = 3.14;
print_bytes(&x, sizeof(x));
print_bytes(&y, sizeof(y));
... to print the actual representation (binary ...
To convert any variable/object to a string that encodes the binary form uses a helper function that converts memory into a "binary" string. This method also handles function pointers. Uses C99 or later.
#include <stdio.h>
#include <assert.h>
#include <limits.h>
// .... compound literal .......
#define VAR_TO_STR_BIN(x) obj_to_bin((char [sizeof(x)*CHAR_BIT + 1]){""}, &(x), sizeof (x))
char *obj_to_bin(char *dest, void *object, size_t osize) {
const unsigned char *p = (const unsigned char *) object;
p += osize;
char *s = dest;
while (osize-- > 0) {
p--;
unsigned i = CHAR_BIT;
while (i-- > 0) {
*s++ = ((*p >> i) & 1) + '0';
}
}
*s = '\0';
return dest;
}
int main(void) {
int i = 42;
double d = 3.1415926535897932384626433832795;
printf("Sample\ndouble pi:%s\nint 42:%s\n", VAR_TO_STR_BIN(d), VAR_TO_STR_BIN(i) );
return 0;
}
Output (Note: depending in endian-ness, results may vary)
Sample
double pi:0100000000001001001000011111101101010100010001000010110100011000
int 42:00000000000000000000000000101010
This approach is easy to adapt to hexadecimal form.
Let's say you have a int variable called memory. Make sure you see how many bits it is; for many processors an int is 32 bits as well as a memory address. So you need to loop through each bit, like this:
unsigned int memory = 1234;
for (int i = 0; i < 32; i++)
{
printf("%d ", memory >> i & 1);
}
This simple method ORs each bit with 1 and shifts each bit by 1.
#include <stdio.h>
#include <stdlib.h>
void print_bits ( void* buf, size_t size_in_bytes )
{
char* ptr = (char*)buf;
for (size_t i = 0; i < size_in_bytes; i++) {
for (short j = 7; j >= 0; j--) {
printf("%d", (ptr[i] >> j) & 1);
}
printf(" ");
}
printf("\n");
}
int main ( void )
{
size_t n;
scanf("%d", &n);
print_bits(&n, sizeof(n));
return 0;
}
This prints bits of the specified object (n here) with the specified size (in bytes).
#dbush, #Anton, I mixed your codes. It's okay?
#include <stdio.h>
#include <stdlib.h>
void print_bytes( void *ptr, size_t size ) ;
int main( void )
{
int x = 123456 ;
double y = 3.14 ;
print_bytes( &x, sizeof(x) ) ;
print_bytes( &y, sizeof(y) ) ;
return 0 ;
}
void print_bytes( void *ptr, size_t size )
{
//char *buf = (char*) ptr;
unsigned char *p = ptr ;
for( size_t i = 0; i < size; i++ )
{
printf( "%02hhX ", p[i] ) ;
}
printf( "\n" ) ;
for( size_t i = 0; i < size; i++ )
{
for( short j = 7; j >= 0; j-- )
{
printf( "%d", ( p[i] >> j ) & 1 ) ;
}
printf(" ");
}
printf("\n");
}
Call print_bits(memory address of variable, size of variable in byte).
void print_bits(void *ptr, int size) //ptr = memory address of variable, size = size of variable in byte
{
long long *ch = ptr;
int size_bits = size * 8;
for(int i = size_bits-1; i>=0; i--){
printf("%lld", *ch >> i & 1) ;
}
}
It has been tested successfully, working with any variable of less than or equal to 64 bits. This will probably work correctly with variables with other sizes (Not Tested).
Calling:
double d = -7.92282286274e+28;
print_bits(&d, sizeof(d));
Output:
1100010111110000000000000000000011100000000000000000000100010111
Introduction
I have an algorithm which takes a pointer to a char array. The algorithm first retrieves the length of the array then reverses the array.
The problem
The problem I have is that I want to use this on a wchar_t array. And want to be able to do this without having to copy the whole function, change the name and the type of the argument.
Here is the mentioned function:
void reverseString(char *str){
unsigned int l = getStringLength(str);
int i = 0;
int m = l >> 1;
while(i < m){
str[i] ^= str[l - 1];
str[l - 1] ^= str[i];
str[i] ^= str[l - 1];
i++;
l--;
}
}
From googling and reading on SO this won't be able to use a void pointer (conceptually same thing using a union) since it would leave me with a solution like this, which to me is equally bad as writing separate functions but with different names and argument types:
void reverseString(void *array, short typeSize){
unsigned int l = getArrayLength(array);
int m = l >> 1;
int i = 0;
char *str = 0;
wchar_t *wstr = 0;
if(typeSize == 1){
str = (char *) array;
while(i < m){
str[i] ^= str[l - 1];
str[l - 1] ^= str[i];
str[i] ^= str[l - 1];
i++;
l--;
}
}else if(typeSize == 4){
wstr = (wchar_t *) array;
while(i < m){
wstr[i] ^= wstr[l - 1];
wstr[l - 1] ^= wstr[i];
wstr[i] ^= wstr[l - 1];
i++;
l--;
}
}
}
Note: getStringLength is just a function which loops through the pointer till it gets to '\0' and returns the iteration sum.
The answer
I am looking for an answer which tells me how to do this in a nicer way without having to rewrite the internals of the algorithm, or an answer saying that it won't be possible to do it any other way. I'm not looking for an answer telling me I should use this and that library which does this for me, because I'm not using this in production code, it's purely educational to get a better understanding of how memory management works and other concepts alike.
Edit: The function I showed is just an example, I'm looking for a universal solution to problems with algorithms alike.
Using "generics" in C is likely to produce code that is noticeably slower and more convoluted / difficult to read / difficult to maintain than the original code. Use the preprocessor if you must do this.
My recommendation is to avoid this technique if at all possible: you should really only use char or wchar_t in your program, not a mixture of both! (char or UChar or almost universally preferable since you can choose the encoding, but I digress...)
#define gchar char
#define gstrlen strlen
#define func_name reverse
#include "reverse_impl.h"
#undef gchar
#undef gstrlen
#undef func_name
#define gchar wchar_t
#define gstrlen wstrlen
#define func_name wreverse
#include "reverse_impl.h"
#undef gchar
#undef gstrlen
#undef func_name
Then, in reverse_impl.h:
void func_name(gchar *str)
{
gchar *p = str, *q = str + gstrlen(str), t;
if (p == q)
return;
q--;
for (; p < q; p++, q--) {
t = *p;
*p = *q;
*q = t;
}
}
Also, DO NOT DO THIS:
x ^= y; // bad!
y ^= x;
x ^= y;
It is more difficult to read and quite possibly much slower to execute.
Also, note that both reverse and wreverse will make garbage if you give them Unicode input: reverse will make malformed output and wreverse can switch the diacritics around or totally screw up Hangul, depending on how they're represented.
It's unlikely to be efficient, but you could easily have your void reverseString(void *array, short typeSize) version reverse the elements via trivial pointer arithmetic and memcpys of the relevant size.
Of course, this approach isn't applicable to every algorithm that you want to make type-agnostic. It's not clear from your question whether you only care about this particular algorithm, or algorithms in general.
[As an aside: Note that using an XOR swap is unlikely to be more efficient than doing it "naively". It's certainly less readable!]
... universal solution ...
The solution is to write something like qsort(): all functions that need to know the size of individual values are passed to your own function with pointers to void all over
#include <math.h>
#include <stdio.h>
#include <wchar.h>
void universalReverseArray(void *arr, size_t siz,
size_t (*arrlen)(void*),
void (*swap)(void*, void*))
{
size_t elems = arrlen(arr);
size_t i = 0;
size_t m = elems >> 1;
unsigned char *p = arr;
while(i < m) {
swap(p + i * siz, p + (elems - 1) * siz);
i++;
elems--;
}
}
void cswap(void *a, void *b) {
char *aa = a, *bb = b;
char t = *aa;
*aa = *bb;
*bb = t;
}
void dswap(void *a, void *b) {
double *aa = a, *bb = b;
double t = *aa;
*aa = *bb;
*bb = t;
}
void wswap(void *a, void *b) {
wchar_t *aa = a, *bb = b;
wchar_t t = *aa;
*aa = *bb;
*bb = t;
}
size_t clen(void *arr) {
char *aa = arr;
size_t retval = 0;
while (*aa) {
retval += 1;
aa += 1;
}
return retval;
}
size_t dlen(void *arr) {
double *aa = arr;
size_t retval = 0;
while (fabs(*aa) >= 0.0001) {
retval += 1;
aa += 1;
}
return retval;
}
size_t wlen(void *arr) {
wchar_t *aa = arr;
size_t retval = 0;
while (*aa) {
retval += 1;
aa += 1;
}
return retval;
}
int main(void) {
double x[] = {1, 2, 3, 4, 5, 0};
char y[] = "foobar";
wchar_t z[4];
z[0] = 'a'; z[1] = 'b'; z[2] = 'c'; z[3] = 0;
for (int k=0; k<5; k++) {printf("%f ", x[k]);}
printf("%s ", y);
printf("%ls\n", z);
universalReverseArray(x, sizeof *x, dlen, dswap);
universalReverseArray(y, sizeof *y, clen, cswap);
universalReverseArray(z, sizeof *z, wlen, wswap);
for (int k=0; k<5; k++) {printf("%f ", x[k]);}
printf("%s ", y);
printf("%ls\n", z);
return 0;
}
You can see it "running" on ideone: http://ideone.com/t1iOg