I have a serious problem with writing an App on Linux.
I have this code
#include <stdio.h>
int main()
{
char ar[10][10];
strcpy(ar[1], "asd");
strcpy(ar[2], "fgh");
int test[2];
test[1] = (int)ar[1];
printf("%s %x | %s %x\n\n", ar[1], ar[1], test[1], test[1]);
return 0;
}
And it works on Windows well, but when i want to run this on Linux i got
Segmentation Fault or Unauthorized Access to memory.
Your program invokes undefined behavior. It assumes that a pointer will fit into an int, which isn't required. Usually pointers will fit on Unix boxes and fail on Windows; but you should use an appropriate integer type, such as intptr_t from stdint.h if you need to do such conversions. Note that strictly speaking the integer must be cast back to a pointer type before being passed to printf.
Using a pointer type to printf and a large enough integral type results in correct behavior: http://ideone.com/HLExMb
#include <stdio.h>
#include <stdint.h>
int main(void)
{
char ar[10][10];
strcpy(ar[1], "asd");
strcpy(ar[2], "fgh");
intptr_t test[2];
test[1] = (intptr_t)ar[1];
printf("%s %x | %s %x\n\n", ar[1], ar[1], (char*)test[1], (char*)test[1]);
return 0;
}
Note though that casting pointers into integral types is generally frowned upon and is likely to result in program bugs. Don't go there unless you absolutely need to do so for one reason or another. When you're starting out in C it is unlikely that you'll ever need to do this.
Related
#include <stdio.h>
#include <stdlib.h>
void main (){
char* shell = getenv("MYSHELL");
if (shell)
printf("%x\n", (unsigned int)shell);
}
shell.c: In function ‘main’:
shell.c:7:19: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
7 | printf("%x\n", (unsigned int)shell);
First of all, that's a warning, not an error. The compiler will still allow you to compile your program when it has warnings (though many programmers would advise fixing those warnings), but if you get a compiler error your code will not compile at all.
The reason for the warning is that char* is a pointer type, which on x64 architectures is essentially a 64-bit integer. int, and by extension unsigned int, is a 32-bit integer. If you want to silence the error, you could cast to unsigned long instead (and change the %x to %lx), but there's a much easier way. There is a format specifier for pointers, %p, which you can simply use with any pointer.
So if you want to silence the warning I'd recommend changing your print statement to printf("%p\n", shell);
I want to make a hack in C for a game I like, but when trying to read the memory from that game, the compiler gives me this warning:
warning: cast to pointer from integer of different size
Which I think is causing problems when trying to read.
Here's the code:
#include <stdio.h>
#include <Windows.h>
#include <stdint.h>
int main(){
int var = 0;
long long addr = 0x7FFEB4BA0FC0;
int pid = 1540;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(hProcess==NULL){
printf("Failed to open Process");
return 0;
}
BOOL rpmReturn = ReadProcessMemory(hProcess, (LPCVOID)addr, &var, 1, NULL);
if(rpmReturn==FALSE){
printf("%llxFailed to read from memory", addr);
return 0;
}
CloseHandle(hProcess);
}
Full error:
Donut.c: In function 'main':
Donut.c:16:47: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
BOOL rpmReturn = ReadProcessMemory(hProcess, (LPCVOID)addr, &var, 1, NULL);
^
I'm using a long long on the address otherwise it would give me an "Overflow" warning which caused problems as well.
I searched everywhere and couldn't find a solution, so I hope someone can help me here.
I'm using gcc on Windows 64bit, BTW.
Solution: Thanks for helping yall! The solution was to install the 64 bit version. Have fun!
From the diagnostic given, it is clear that you are building your application as 32bit - as it is the only possible reason for the size of pointer to not be equal to size of long long int.
However, you can't use int directly instead of long integer, because the hexadecimal constant you have there would not fit into 32bit integer.
I have no idea where the magic address comes from, but you can't use it in 32bit program. Possible solutions would be to either compile program as 64bit, or change the address to one fitting into 32bit (again, this is unclear where it comes from in the first place).
I have this code:
#include <stdio.h>
#include <string.h>
void main(){
printf("%p");
}
This is the output:
0x7ffdd9b973d8
I know %p stands for pointer and when using it as for example
#include <stdio.h>
#include <string.h>
void main(){
int i = 0;
printf("%p", i);
}
it returns the pointer address of i. But my question is what does it return when not adding any other argument in the printf function just printf("%p")
Trash. printf uses a variable-length argument list. It uses the format string to determine how many arguments you actually passed. If you did not actually pass anything in, it will still read from basically arbitrary portions of memory as though you did. The result is undefined/trash.
Some compilers will be able to catch this situation with a warning because the printf family of functions is so popular. Some cases may crash your system if the function tries to read from memory you do not have access to. There is no way to tell how it will behave next time even if you have obtained a certain result.
But my question is what does it return when not adding any other argument in the printf function just printf("%p");
Anything. Nothing. Random junk. Maybe it crashes.
There is no way to know without investigating a specific combination of compiler, CPU, platform, libraries, execution environment, and so on. There is no rule that requires it to operate any particular way.
The behavior of
printf("%p");
is undefined. When you specify a %p format in the format string, the corresponding argument of void * (or char *) type shall be present in the argument list.
I am trying to create a C program in a Linux VM that uses a char array. I found that every time I try to do anything to the array, e.g. sizeof(), I get a segmentation fault. I wrote a test program that just made an array and got sizeof() as a test, and sure enough I get the same error.
I think this is related to the program running in a VM. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#define ARR_LENGTH(x) sizeof(x) / sizeof(x[0])
int main()
{
printf("Hllo world!\n");
int sent = 10;
char hello[] = {'a','b','c','d','e','f','g','h'};
printf(sizeof(hello));
printf(ARR_LENGTH(hello));
return 0;
}
Am I missing something, or is the VM likely the problem?
You just need to read the printf() documentation carefully. It doesn't take an integer as its first argument.
The problematic lines are:
printf(sizeof(hello));
printf(ARR_LENGTH(hello));
It should be:
printf("%zu\n", sizeof(hello));
printf("%zu\n", ARR_LENGTH(hello));
(%zu is the format specifier to print size_t values).
My gcc compiler produces the warning:
warning: passing argument 1 of ‘printf’ makes pointer from integer
without a cast [-Wint-conversion]
for those two statements. Up the compiler warning levels (in case you don't get them alrready).
I've started learning C and pointers and I've been working on tutorials on the internet. I assume that the code should work as it is in a tutorial, and it seems right to me, but I get a segmentation error. The code is:
#include <stdio.h>
#include <stdlib.h>
/*
*
*/
int main(int argc, char** argv) {
float fl = 3.14;
unsigned int addr = (unsigned int) &fl;
printf("fl's address=%u\n", addr);
printf("addr's contents = %.2f\n", * (float*) addr);
return (EXIT_SUCCESS);
}
The error that I get is
/Applications/NetBeans/NetBeans
6.9.1.app/Contents/Resources/NetBeans/ide/bin/nativeexecution/dorun.sh: line 33: 1626
Segmentation fault sh "${SHFILE}"
Does this have to do with me using a Mac or is there something wrong with the code?
Thanks a lot,
Niek
Try this instead:
int main(int argc, char** argv) {
float fl = 3.14;
float *addr = &fl;
printf("fl's address=%p\n", addr);
printf("addr's contents = %.2f\n", *addr);
return (EXIT_SUCCESS);
}
That may be undefined behaviour. There's no guarantee that an int and a pointer can hold the same value, and you should not be casting between them. Use a float* instead.
C99 6.3.2.3/5 and /6 state:
5: An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.
6: Any pointer type may be converted to an integer type. Except as previously specified, the
result is implementation-defined. If the result cannot be represented in the integer type,
the behavior is undefined. The result need not be in the range of values of any integer
type.
Yes, the address space of pointer is not guaranteed to be the same as an int. In fact, this code gives me the following compilation warnings using gcc on a Mac Pro:
test.c:9: warning: cast from pointer to integer of different size
test.c:11: warning: cast to pointer from integer of different size
and a seg fault as well. I would consider samplebias' code.
The code seems to be correct, compiling with MinGW GCC and running gives the following output:
fl's address=2293528
addr's contents = 3.14
yes under win7 + mingw32, the code compiles\executes corrrectly
fl's address=2293572
addr's contents = 3.14
i think it's problem with MacOS only
The problem is the size of int. As #paxdiablo already said, there is no guarantee that an int is big enough to hold the same value as a pointer. Try long longinstead, but be warned, the code stays in the undefined behavior corner.