warning:" initialization makes pointer from integer without a cast in c - c

for( k = 0; k < CycleCount;k++)
{
//make Org data
int* Data = MakeData(DataCount[i]);
......
the function look like this one.
i think this is right. so ...
int* MakeData(int DataCount)
{
//
int* Data=(int*)malloc(DataCount*sizeof(int));
int i;
for( i=0; i<DataCount; i++)
{
//
Data[i] = rand()%DataCount +1;
}
return Data;
}
i dont know why this didn't work.
what shoud i have to do???

When the C compiler finds a function call without having seen a function prototype it assumes a function that returns an int.
You should tell the compiler the correct function signature with the "function prototype":
int* MakeData(int DataCount);
This should be placed in a .h file that will be included in all compilation units that call or define the function.
If you have a static function, that is visible only in the current compilation unit, you can place the prototype (incl. static) before all functions in that file.
Further you should never cast the return from malloc. It returns a void*. In the language C this can be converted to any other pointer type. You get the correct prototype when you #include <stdlib.h>.

Related

Warning: Return from incompatible pointer type

The code below is producing a compiler warning: return from incompatible pointer type. The type I'm returning seems to be the issue but I cant seem to fix this warning.
I have tried changing the type of hands to int *. Also have tried returning &hands.
int * dealDeck(int numPlayers, int numCards, int cardDeck[])
{
static int hands[MAX_PLAYERS][MAX_CARDS]={0};
int start = 0;
int end = numCards;
int player, hand, j;
int card;
for(player = 0; player < numPlayers; player++)
{
for(hand = start, j=0; hand < end; hand++,j++)
{
card = cardDeck[hand];
hands[player][j] = card;
}
start = end;
end += numCards;
}
return hands;
}
This function should return a pointer to the array "hands". This array is then passed to another function which will print out its elements.
The hands variable is not an int * this is a int **
So you need to return a int **
This is a 2d array.
First of all, you have declared return type of int *, which would mean, that you are trying to return an array, while you want to return a 2-dimensional array. The proper type for this would usually be int **, but that won't cut it here. You opted to go with static, fixed size array. That means, that you need to return pointer to some structures of size MAX_CARDS * sizeof(int) (and proper type, which is the real problem here). AFAIK, there is no way to specify that return type in C*.
There are many alternatives though. You could keep the static approach, if you specify only up to 1 size (static int *hands[MAX_PLAYERS] or static int **hands), but then you need to dynamically allocate the inner arrays.
The sane way to do it is usually "call by reference", where you define the array normally before calling the function and you pass it as a parameter to the function. The function then directly modifies the outside variables. While it will help massively, with the maintainability of your code, I was surprised to find out, that it doesn't get rid of the warning. That means, that the best solution is probably to dynamically allocate the array, before calling the function and then pass it as an argument to the function, so it can access it. This also solves the question of whether the array needs to be initialized, and whether = {0} is well readable way to do it (for multidimensional array) , since you'll have to initialize it "manually".
Example:
#include <stdio.h>
#include <stdlib.h>
#define PLAYERS 10
#define DECKS 20
void foo(int **bar)
{
bar[0][0] = 777;
printf("%d", bar[0][0]);
/*
* no point in returning the array you were already given
* but for the purposes of curiosity you could change the type from
* void to int ** and "return bar;"
*/
}
int main()
{
int **arr;
arr = malloc(sizeof(int *) * PLAYERS);
for (size_t d = 0; d < DECKS; d++) {
/* calloc() here if you need the zero initialization */
arr[d] = malloc(sizeof(int) * DECKS);
}
foo(arr);
return 0;
}
*some compilers call such type like int (*)[20], but that isn't valid C syntax

C conflicting type bug

When I try to compile this I'm being told by gcc that I have conflicting types for pack_cui(C).
I don't see how I could be getting conflicting types as I know I'm passing in a char*. I'm new to C so I'm sure I'm missing something obvious.
int main(){
char* C = malloc(sizeof(char) * 4);
C[0] = 1;
C[1] = 2;
C[2] = -1;
C[3] = 4;
pack_cui(C);
return 0;
}
unsigned int pack_cui(char* C){
unsigned int new_int = 0;
unsigned int i;
for(i = 0; i < 4; i++){
new_int = new_int | (unsigned int)(signed int)C[i];
if(i != 3) new_int = new_int << 8;
}
return new_int;
}
The error I received was
hw12.c:17:14: error: conflicting types for ‘pack_cui’
unsigned int pack_cui(char* C){
^
hw12.c:13:5: note: previous implicit declaration of ‘pack_cui’ was here
pack_cui(C);
Add a prototype for pack_cui before main:
unsigned int pack_cui(char* C);
Otherwise, when the compiler sees the call to pack_cui, it has to guess the type, and in this case it guesses wrong.
When you call an undeclared function, the C89 standard mandates an implicit declaration. This declaration would be:
int pack_cui();
The () is not the same as (void), it indicates that the function takes an unspecified number of arguments, whereas (void) means zero. This is left over from pre-ISO/ANSI C, back in the K&R days.
You don't want that, because that is the wrong declaration. Create your own declaration at the top, above main():
unsigned pack_cui(char *);
Move the definition of pack_cui from below the main function, to above the main function. Or set up and include a header file that declares pack_cui.
Also, once this is done, recompile with warnings enabled, so that you catch the other issue with your code:
$ gcc -Wall foo.c
You should include stdlib.h, at least.
When you call a C function, whether it's one of your own or one declared by the standard library, you must have a visible declaration of that function so the compiler knows how to generate the code to call it. That declaration should be a prototype, i.e., a declaration that specifies the types of the function's parameters. A function definition (with the { ... } containing the code that implements the function) provide a declaration.
In your example, no declaration of pack_cui is visible at the point of the call; it's not defined until later.
You can fix this by moving the definition of pack_cui above the definition of main, or by adding a "forward declaration" and leaving the definitions where they are.
The latter would look like this:
unsigned int pack_cui(char* C); /* a declaration, not a definition */
int main(void) { /* definition of main */
/* ... */
}
unsigned int pack_cui(char* C) { /* definition of pack_cui */
/* ... */
}
Either approach is acceptable.
For much the same reason, you need to provide a declaration for the malloc function. You should do this by adding
#include <stdlib.h>
to the top of your source file.

Returning Void Pointer Truncates Value

I'm having trouble returning a void pointer to another function in C.
HEADER FILE:
void *function2( void );
MAIN.C
#include "myHeader.h"
void function1 (){
void *temp = NULL;
temp = function2();
}
FUNCTION2.C
int a = 3;
void *function2(void){
printf("Memory Address %p\n",&a );
return (void *) &a; // value of &a is 0x100023444
}
However, the value of temp in function1() is 0x3444,instead of 0x100023444.
Does anyone know a solution for this, or if I am doing something wrong?
EDITED:
It seems, the header was added in the wrong place, leading to the problem described by AndreyT and Jonathan below, which seems to have fixed the truncation problem. Thanks for your help guys!
Given the revision to the question, I'm confident the problem is that you did not declare function2() before you used it. Consequently, the compiler thinks it returns an int, not a void *. It should also be complaining about the actual definition not matching the assumed declaration.
You should make sure your compiler options require you to define or declare a full prototype for each function before you use it.
Note that you should declare void *function2(void); because omitting the void in the parameter list means something quite different — it means the compiler is not told anything about what parameters it takes, not that it takes no parameters. (This is a difference from C++.)
You still have problems because you're returning a pointer to a local variable. You can probably print the pointer (though even that is not guaranteed by the standard), but you cannot reliably use it.
extern void *function2(void);
void function1(void)
{
void *temp = function2();
printf("Address: %p\n", temp);
}
void *function2(void)
{
int a = 3;
printf("Address: %p\n", &a);
return &a; // value of &a is 0x1200001234
}
Or define function2() before defining function1().
Note that it is crucial to include the header both where the function is defined (to make sure the definition is consistent with the header) and where the function is used (to make sure the use is consistent with the header). As long as you do this, all will be well.
Inside function1 you are calling a yet-undeclared function function2. In classic C language (C89/90) this is allowed, but an undeclared function is assumed to return an int. Apparently, on your platform pointers are 64 bits wide and int is 32 bits wide. This is what causes a truncation of your 64-bit pointer value 0x1200001234 to 32 bits, giving you 0x1234.
Formally, your code has undefined behavior, since after causing the compiler to assume that function2 returns int you declared it as returning void *. Even C89/90 compilers usually issue a warning about this problem (and C99 compiler report an error). Did you ignore it?
Either move the entire definition of function2 up and place it above function1
void *function2(void) {
int a = 3;
return &a;
}
void function1 (void){
void *temp = NULL;
temp = function2();
}
Or, alternatively, declare function2 before calling it
void *function2(void);
void function1(void) {
void *temp = NULL;
temp = function2();
}
void *function2(void) {
int a = 3;
return &a;
}
You have to declare your functions before you call them (preferably with prototype).
This answer is apart from truncation.
In function2() a is local variable. Here scope and lifetime od a limited to the function2. So returning the address to other function is illegal. It will cause undefined behavior. Please pay more attention to learn storage class in C

Problem with the following code

I want to the know the problems with the code presented below. I seem to be getting a segmentation fault.
void mallocfn(void *mem, int size)
{
mem = malloc(size);
}
int main()
{
int *ptr = NULL;
mallocfn(ptr, sizeof(ptr));
*ptr = 3;
return;
}
Assuming that your wrapper around malloc is misnamed in your example (you use AllocateMemory in the main(...) function) - so I'm taking it that the function you've called malloc is actually AllocateMemory, you're passing in a pointer by value, setting this parameter value to be the result of malloc, but when the function returns the pointer that was passed in will not have changed.
int *ptr = NULL;
AllocateMemory(ptr, sizeof(ptr));
*ptr = 3; // ptr is still NULL here. AllocateMemory can't have changed it.
should be something like:
void mallocfn(void **mem, int size)
void mallocfn(int **mem, int size)
{
*mem = malloc(size);
}
int main()
{
int *ptr = NULL;
mallocfn(&ptr, sizeof(ptr));
*ptr = 3;
return;
}
Because you need to edit the contents of p and not something pointed b p, so you need to send the pointer variable p's address to the allocating function.
Also check #Will A 's answer
Keeping your example, a proper use of malloc would look more like this:
#include <stdlib.h>
int main()
{
int *ptr = NULL;
ptr = malloc(sizeof(int));
if (ptr != NULL)
{
*ptr = 3;
free(ptr);
}
return 0;
}
If you're learning C I suggest you get more self-motivated to read error messages and come to this conclusion yourself. Let's parse them:
prog.c:1: warning: conflicting types for built-in function ‘malloc’
malloc is a standard function, and I guess gcc already knows how it's declared, treating it as a "built-in". Typically when using standard library functions you want to #include the right header. You can figure out which header based on documentation (man malloc).
In C++ you can declare functions that have the same name as already existing functions, with different parameters. C will not let you do this, and so the compiler complains.
prog.c:3: warning: passing argument 1 of ‘malloc’ makes pointer from integer without a cast
prog.c:3: error: too few arguments to function ‘malloc’
Your malloc is calling itself. You said that the first parameter was void* and that it had two parameters. Now you are calling it with an integer.
prog.c:8: error: ‘NULL’ undeclared (first use in this function)
NULL is declared in standard headers, and you did not #include them.
prog.c:9: warning: implicit declaration of function ‘AllocateMemory’
You just called a function AllocateMemory, without telling the compiler what it's supposed to look like. (Or providing an implementation, which will create a linker error.)
prog.c:12: warning: ‘return’ with no value, in function returning non-void
You said that main would return int (as it should), however you just said return; without a value.
Abandon this whole idiom. There is no way to do it in C without making a separate allocation function for each type of object you might want to allocate. Instead use malloc the way it was intended to be used - with the pointer being returned to you in the return value. This way it automatically gets converted from void * to the right pointer type on assignment.

Passing pointers of arrays in C

So I have some code that looks like this:
int a[10];
a = arrayGen(a,9);
and the arrayGen function looks like this:
int* arrayGen(int arrAddr[], int maxNum)
{
int counter=0;
while(arrAddr[counter] != '\0') {
arrAddr[counter] = gen(maxNum);
counter++;
}
return arrAddr;
}
Right now the compilier tells me "warning: passing argument 1 of ‘arrayGen’ makes integer from pointer without a cast"
My thinking is that I pass 'a', a pointer to a[0], then since the array is already created I can just fill in values for a[n] until I a[n] == '\0'. I think my error is that arrayGen is written to take in an array, not a pointer to one. If that's true I'm not sure how to proceed, do I write values to addresses until the contents of one address is '\0'?
The basic magic here is this identity in C:
*(a+i) == a[i]
Okay, now I'll make this be readable English.
Here's the issue: An array name isn't an lvalue; it can't be assigned to. So the line you have with
a = arrayGen(...)
is the problem. See this example:
int main() {
int a[10];
a = arrayGen(a,9);
return 0;
}
which gives the compilation error:
gcc -o foo foo.c
foo.c: In function 'main':
foo.c:21: error: incompatible types in assignment
Compilation exited abnormally with code 1 at Sun Feb 1 20:05:37
You need to have a pointer, which is an lvalue, to which to assign the results.
This code, for example:
int main() {
int a[10];
int * ip;
/* a = arrayGen(a,9); */
ip = a ; /* or &a[0] */
ip = arrayGen(ip,9);
return 0;
}
compiles fine:
gcc -o foo foo.c
Compilation finished at Sun Feb 1 20:09:28
Note that because of the identity at top, you can treat ip as an array if you like, as in this code:
int main() {
int a[10];
int * ip;
int ix ;
/* a = arrayGen(a,9); */
ip = a ; /* or &a[0] */
ip = arrayGen(ip,9);
for(ix=0; ix < 9; ix++)
ip[ix] = 42 ;
return 0;
}
Full example code
Just for completeness here's my full example:
int gen(int max){
return 42;
}
int* arrayGen(int arrAddr[], int maxNum)
{
int counter=0;
while(arrAddr[counter] != '\0') {
arrAddr[counter] = gen(maxNum);
counter++;
}
return arrAddr;
}
int main() {
int a[10];
int * ip;
int ix ;
/* a = arrayGen(a,9); */
ip = a ; /* or &a[0] */
ip = arrayGen(ip,9);
for(ix=0; ix < 9; ix++)
ip[ix] = 42 ;
return 0;
}
Why even return arrAddr? Your passing a[10] by reference so the contents of the array will be modified. Unless you need another reference to the array then charlies suggestion is correct.
Hmm, I know your question's been answered, but something else about the code is bugging me. Why are you using the test against '\0' to determine the end of the array? I'm pretty sure that only works with C strings. The code does indeed compile after the fix suggested, but if you loop through your array, I'm curious to see if you're getting the correct values.
I'm not sure what you are trying to do but the assignment of a pointer value to an array is what's bothering the compiler as mentioned by Charlie. I'm curious about checking against the NUL character constant '\0'. Your sample array is uninitialized memory so the comparison in arrayGen isn't going to do what you want it to do.
The parameter list that you are using ends up being identical to:
int* arrayGen(int *arrAddr, int maxNum)
for most purposes. The actual statement in the standard is:
A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.
If you really want to force the caller to use an array, then use the following syntax:
void accepts_pointer_to_array (int (*ary)[10]) {
int i;
for (i=0; i<10; ++i) {
(*ary)[i] = 0; /* note the funky syntax is necessary */
}
}
void some_caller (void) {
int ary1[10];
int ary2[20];
int *ptr = &ary1[0];
accepts_pointer_to_array(&ary1); /* passing address is necessary */
accepts_pointer_to_array(&ary2); /* fails */
accepts_pointer_to_array(ptr); /* also fails */
}
Your compiler should complain if you call it with anything that isn't a pointer to an array of 10 integers. I can honestly say though that I have never seen this one anywhere outside of various books (The C Book, Expert C Programming)... at least not in C programming. In C++, however, I have had reason to use this syntax in exactly one case:
template <typename T, std::size_t N>
std::size_t array_size (T (&ary)[N]) {
return N;
}
Your mileage may vary though. If you really want to dig into stuff like this, I can't recommend Expert C Programming highly enough. You can also find The C Book online at gbdirect.
Try calling your parameter int* arrAddr, not int arrAddr[]. Although when I think about it, the parameters for the main method are similar yet that works. So not sure about the explanation part.
Edit: Hm all the resources I can find on the internet say it should work. I'm not sure, I've always passed arrays as pointers myself so never had this snag before, so I'm very interested in the solution.
The way your using it arrayGen() doesn't need to return a value. You also need to place '\0' in the last element, it isn't done automatically, or pass the index of the last element to fill.
#jeffD
Passing the index would be the preferred way, as there's no guarantee you won't hit other '\0's before your final one (I certainly was when I tested it).

Resources