I wish to create the following:
int amount[i];
As a global variable (to practice using threads and mutexes) but the variable i is defined at launch of the program:
./a.out 10
How may I take the value through the main (argv[1]) and create the global accordingly?
You can use global pointer variable and then allocate memory based on argv[1].
int *amount;
int main(int argc, char *argv[])
{
int count = atoi(argv[1]);
amount = malloc(count * sizeof(int));
...
free(amount);
return 0;
}
You're trying to use a variable length array at global scope. This won't work (globals need to have a constant, known size, otherwise compilation would be difficult).
IMHO, you shouldn't be using a global in the first place. Better use a local variable, and pass it via argument to the functions / parts of your program that need access to it.
IMHO, you shouldn't be using VLA in the first place.
I'd go with something like this:
int main(int argc, char ** argv) {
// check arguments, not done here!
int value = atoi(argv[1]);
// Check that it's actually usable as a size!
size_t count;
if (value >= 0) {
count = value;
}
else {
// Fires of hell here
exit(1);
}
int * amount = malloc(sizeof(int) * count); // add error check, please!
// use at will
free(amount);
return 0;
}
If you insist on using a global, then there's the possibility to make the (constant sized) pointer amount a global variable.
Also: Using heap allocated data instead of stack allocated if you'd use a VLA is to be preferred when accessing the data from a detached thread, because the VLA could already be out of scope when the thread tries to access it!
Use constexpr keyword to make any non-const variable as constexpr. It will avoid the compiler errors, but be careful about the variable.
For example:
#include<iostream.h>
constexpr int afun()
{
return(3);
}
enum
{
TOTAL_NO_OF_PACKETS = afun() // You can use for Enum also
};
unsigned packets[afun()]; // Using in Global array
void main()
{
// **
}
It's not possible to create global variables using the user input. See basically you can use global variables by defining them in the program code.
Related
I am attempting to have a gobal counter the can can used by any function in the program. Is this possible?
int* count;
main(){
*count = 0;
}
void incrementCount(){
++*count;
}
int getCount(){
return *count;
}
If not possible how can I do something similar?
No need to take a pointer. Take a Variable like
int count;
If you are going to use it in a single file better to declare it static.
A much better approach would be using the getter and setter functions instead of updating global variable everywhere
I am attempting to have a gobal counter the can can used by any function in the program. Is this possible?
Yes, even though it's not a good thing to use global variable.
All you need to do is to declare the function in global scope. You should also initialise it in main before any function call.
int count;
int main()
{
count = 0;
incrementCount();
...
}
There is no need to use pointer in your case. And it's wrong as well, because you have not allocate any memory for that pointer.
Firstly there are few issues in the shared code sample. Here
int* count; /* count is pointer i.e you need to make count to hold or point to some valid memory location */
count is of int pointer type. And here
*count = 0; /* de-referencing uninitiated pointer */
you are trying to de-reference count which has not valid memory. It causes segmentation fault. Before de-referencing you need to allocate memory. for e.g
count = malloc(sizeof(*count));
/* error handling of malloc return value */
*count = 0;
I am attempting to have a gobal counter the can can used by any
function in the program ?
You can do the same task without using pointer, try using static if use having file scope. If possible avoid using global variable.
You can just declare the variable as integer (not pointer).
You can have a global getter and setter function. Also initialize the global variable before any function call, best will be in Main().
first, you can't do
*count = 0;
if you don't have initialised your pointer, it means refrenced to a
variable like:
count = &x;
Then, if you want that variable is shared and the value is always
updated between methods you can simply declare the variable as
"static",
#include <stdio.h>
static int count;
main(){
printf("%d",count);
}
void incrementCount(){
++count;
}
int getCount(){
return count;
}
Not using C that often, I came across a possibly simple problem. I have several functions, that need access to a global array-variable g. But the actual size of this variable has to be defined in an init()-function. The size depends on some other stuff, so g has to be declared somehow with a dynamic size. I read about malloc and other functions, but I am not sure how to use them properly.
Example:
double g[dynamic]; // size is not known yet
int n;
void init()
{
// calculate "n" for array size
n = ...
// declare and initialze g with a size "n"
}
void dostuff()
{
for (int i = 0; i < n; i++)
work(g[i]);
}
How should I solve this?
You cannot use an array. You must use a pointer.
double *global_array; // size is not known yet
size_t nglobal_array; // may be helpful to have the size
void init(void)
{
// calculate "nglobal_array" for array size
nglobal_array = 42;
// declare and initialze global_array with a size "nglobal_array"
global_array = malloc(nglobal_array * sizeof *global_array);
if (global_array == NULL) {
fprintf(stderr, "Error allocating resources.\nProgram aborted.\n");
exit(EXIT_FAILURE);
}
}
void dostuff()
{
for (int i = 0; i < nglobal_array; i++)
work(global_array[i]);
}
Don't forget to free(global_array) when you no longer need it.
Complete usage would then be something like this
#include <stdlib.h>
// includes
// declarations & definitions as above
int main(void) {
init();
dostuff();
free(global_array);
}
What you want to achieve is not possible in C.
A global array must have a fixed size at compile, or at least at link time.
You can declare the array without a specified size:
extern double g[];
But it must be defined somewhere with an actual size, computed from a constant expression at the definition place, and the size cannot be determined from the above declaration, so it must be passed some other way to the functions that will use the array: either implicitly, with a special value signifying the end of the array (like '\0' for char strings) or explicitly via a separate variable as you posted. Note however that n and g are very poor name choices for global variables as they are likely to clash with local variable names and convey no meaning to the reader.
If the size is not known until run time, you should define a pointer instead of an array and also define a separate variable with the length of the array that will be allocated by the initialization function.
double *g;
size_t g_length;
No. C doesn't do that. Arrays declared in global scope have fixed space allocated for them in your binary(.EXE files on Windows and ELF executables on Linux). If you want an array of dynamic size, you need to dynamically allocate it.
Example is here:
#include <stdlib.h>
#define ARRAY_SIZE 100
typedef char T; //your type here
T* array;
void init() {
array = malloc(sizeof(T) * ARRAY_SIZE); //array filled with garbage values
//array = calloc(ARRAY_SIZE, sizeof(T)); //array filled with 0x00
}
void finish() {
free(array); // DO NOT ACCESS ARRAY AFTER THIS CALL!
}
int main() {
init();
array[6] = 63; //access array as normal
finish();
//array[41] = 23; //will most likely crash due to a segmentation fault, also called an access violation on Windoez
}
Here's the code:
int EdgeCount = 0;
int numOfEdges = 0;
void addEdge() {
// some code
numOfEdges++;
}
int EdgeWeightArray[numOfEdges]; // error
I want that global array with variable parameters to use it later but I couldn't do that because without #define we can't define globally arrays parameters; and #define is not a variable thing. In my code numOfEdges is variable and I couldn't make it constant.
EdgeWeightArray has global scobe, so it must be a fixed size. But numOfEdges is of course not a constant expression.
What size do you expect EdgeWeightArray to be? Do you expect it to grow when you increment numOfEdges? If so, you nwed to look into dynamic memory allocation; namely malloc and realloc.
Brief example with no error checking:
int numOfEdges = 0;
int *EdgeWeightArray;
void addEdge(some parameters) {
//SOME CODE
numOfEdges++;
EdgeWeightArray = realloc(EdgeWeightArray, numOfEdges * sizeof(EdgeWeightArray[0]));
}
Why not use a global int pointer and allocate memory with malloc() with desired number of elements?
What you are trying to do is not possible because memory for global variables are calculated at compile time and the value of numOfEdges is updated at runtime.
In my eyes, you want to create a not well designed code, where the size has global scope and the vector has to have local scope in order to be stored in the stack (according to your starting point). Anyway, you might do something like that:
void defineSize() {
numOfEdges++;
}
void useIt()
{
int EdgeWeightArray[numOfEdges];
/* Use EdgeWeightArray, once the function has been executed, \
EdgeWeightArray will dissapear */
}
This is an expansion to Jonathons answer.
If you already know how many Elements there will be at maximum for your array you could use a fixed size for your array. This could be faster in the moment, because there is no reallocation happening.
But you have to make sure to do appropriate error handling with this approach. It can be quite error prone.
You would then need a counter to keep track of your Edges, but you appear to already have one of those.
Your code would then look like:
#define MAX_EDGE_COUNT 1000
int EdgeCount = 0;
void addEdge() {
// some code
EdgeWeightArray[EdgeCount] = newEdge;
EdgeCount++;
}
int EdgeWeightArray[MAX_EDGE_COUNT];
Before you feel the need to mark this as a duplicate post, please don't. I have read all the threads on pointers, arrays, and functions I could find but almost all of them are far too advanced to be of any help to me.
I'm not getting an error, however my code will not print my array. It seems the issue here is using scanf. I don't think the values entered are actually being put into the array in main(). I've tried using pointers, but then I get the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)" whenever I try to use scanf to collect user inputted values to put into the array.
What I am working on is limited to declaring my array in the main() function, but all the operations are to be performed in promptData() function. Any help would be great, I'm at my wits end trying to figure this out on my own.
#import <stdio.h>
void promptData(double data[], int numElem);
int main(int argc, const char * argv[])
{
int size, i;
double array[size];
promptData(array, size);
for (i = 0; i < size; i++)
printf("%.2lf\n", array[i]);
return 0;
}
void promptData(double data[], int numElem)
{
int i;
printf("Enter integer values for size of array.\n");
scanf("%i", &numElem);
for (i = 0; i < numElem; i++)
{
printf("Enter array values.\n");
scanf("%lf", &data[i]);
}
}
Your program has undefined behaviour because variable size was not initialized and has indeterminate value.
You should at first in main ask the user to enter the size of the array then define the array itself and only after that fill it with values.
For example
int main(int argc, const char * argv[])
{
int size = 0;
printf( "Enter a positive integer value for the size of the array: ");
scanf( "%i", &size);
if ( size == 0 ) exit( 1 );
double array[size];
promptData(array, size);
//...
Also in C there is no such a directive as
#import <stdio.h>
Use instead
#include <stdio.h>
At least in ANSI C 89 and C 90, you can't give a variable as the size of an array. The size of array should be known at compile time. You should be doing something like double array[size];.
Even in C99, where you can have variable sized arrays; the variables should contain proper index values at the time you declare the array. In that case, you should read the number from stdin and then declare the array.
Also in C, all parameters are passed by value. This means every function takes a copy of the parameters in the function. If you want to modify a variable's value, you should pass a pointer to it, and then modify the pointer's dereferenced value, something like:
void change(int *x)
{
*x = 7;
}
void first(void)
{
int x = 5;
change(&x);
printf("%d\n", x);
}
Adding on to the other, correct, answer by Zenith, if you want a dynamically allocated array (like you want to be able to change its size based on user input), then your only option is to use one of the memory allocation functions like malloc().
Once you actually have the size in your main function, declare your array like this:
int *myArray = malloc(sizeof(int) * size));//note that malloc will return a NULL if it fails
//you should always check
if(myArray != null) {
//do stuff with myArray like you were. You can just use myArray[] as long as you
//make SURE that you don't go beyond 'size'
}
free(myArray);
//VERY important that every malloc() has a free() with it
Note: untested, but the idea is there.
Further, to answer your other question.
If you find yourself in a situation where you need to call a function and use things INSIDE that function to change stuff where you called it, you have only two choices in C.
You can either return the value and assign it to a variable in the calling function like this:
int result = myFunction(someVariable, anotherVariable);
//do stuff with result
Or, use pointers.
I'm not explaining pointers here, that's usually several lectures worth of information, and is one of the more difficult concepts to grasp for introductory programmers. All I can tell you is you need to learn them, but this format is not the right way to go about doing that.
You're passing size to promptData as a copy.
Thus changes to numElem inside promptData will not affect the size variable in your main. Hence size remains uninitialized, i.e. has an undefined value and therefore should not be used as a size for an array.
If you need to initialize an array with a size that's only known at run-time, you need to allocate memory for the array dynamically using malloc, for example:
double* array = malloc(size * sizeof(double));
I've just started learning C (coming from a C# background.) For my first program I decided to create a program to calculate factors. I need to pass a pointer in to a function and then update the corresponding variable.
I get the error 'Conflicting types for findFactors', I think that this is because I have not shown that I wish to pass a pointer as an argument when I declare the findFactors function. Any help would be greatly appreciated!
#include <stdio.h>
#include <stdlib.h>
int *findFactors(int, int);
int main (int argc, const char * argv[])
{
int numToFind;
do {
printf("Enter a number to find the factors of: ");
scanf("%d", &numToFind);
} while (numToFind > 100);
int factorCount;
findFactors(numToFind, &factorCount);
return 0;
}
int *findFactors(int input, int *numberOfFactors)
{
int *results = malloc(input);
int count = 0;
for (int counter = 2; counter < input; counter++) {
if (input % counter == 0){
results[count] = counter;
count++;
printf("%d is factor number %d\n", counter, count);
}
}
return results;
}
Change the declaration to match the definition:
int *findFactors(int, int *);
I apologise for adding yet another answer but I don't think anyone has covered every point that needs to be covered in your question.
1) Whenever you use malloc() to dynamically allocate some memory, you must also free() it when you're done. The operating system will, usually, tidy up after you, but consider that you have a process during your executable that uses some memory. When said process is done, if you free() that memory your process has more memory available. It's about efficiency.
To use free correctly:
int* somememory = malloc(sizeyouwant * sizeof(int));
// do something
free(somememory);
Easy.
2) Whenever you use malloc, as others have noted, the actual allocation is in bytes so you must do malloc(numofelements*sizeof(type));. There is another, less widely used, function called calloc that looks like this calloc(num, sizeof(type)); which is possibly easier to understand. calloc also initialises your memory to zero.
3) You do not need to cast the return type of malloc. I know a lot of programming books suggest you do and C++ mandates that you must (but in C++ you should be using new/delete). See this question.
4) Your function signature was indeed incorrect - function signatures must match their functions.
5) On returning pointers from functions, it is something I discourage but it isn't wrong per se. Two points to mention: always keep 1) in mind. I asked exactly what the problem was and it basically comes down to keeping track of those free() calls. As a more advanced user, there's also the allocator type to worry about.
Another point here, consider this function:
int* badfunction()
{
int x = 42;
int *y = &x;
return y;
}
This is bad, bad, bad. What happens here is that we create and return a pointer to x which only exists as long as you are in badfunction. When you return, you have an address to a variable that no longer exists because x is typically created on the stack. You'll learn more about that over time; for now, just think that the variable doesn't exist beyond its function.
Note that int* y = malloc(... is a different case - that memory is created on the heap because of the malloc and therefore survives the end of said function.
What would I recommend as a function signature? I would actually go with shybovycha's function with a slight modification:
int findFactors(int* factors, const int N);
My changes are just personal preference. I use const so that I know something is part of the input of a function. It isn't strictly necessary with just an int, but if you're passing in pointers, remember the source memory can be modified unless you use const before it, whereon your compiler should warn you if you try to modify it. So its just habit in this case.
Second change is that I prefer output parameters on the left because I always think that way around, i.e. output = func(input).
Why can you modify function arguments when a pointer is used? Because you've passed a pointer to a variable. This is just a memory address - when we "dereference" it (access the value at that address) we can modify it. Technically speaking C is strictly pass by value. Pointers are themselves variables containing memory addresses and the contents of those variables are copied to your function. So a normal variable (say int) is just a copy of whatever you passed in. int* factors is a copy of the address in the pointer variable you pass in. By design, both the original and this copy point to the same memory, so when we dereference them we can edit that memory in both the caller and the original function.
I hope that clears a few things up.
EDIT: no reference in C (C++ feature)
Don't forget to modify numberOfFactors in the method (or remove this parameter if not useful). The signature at the beginning of your file must also match the signature of the implementation at the end (that's the error you receive).
Finally, your malloc for results is not correct. You need to do this:
int *results = malloc(input * sizeof(int));
int* ip <- pointer to a an int
int** ipp <- pointer to a pointer to an int.
int *findFactors(int, int); line says you wanna return pointer from this function (it's better to use asteriks closer to the type name: int* moo(); - this prevents misunderstandings i think).
If you wanna dynamically change function argument (which is better way than just return pointer), you should just use argument as if you have this variable already.
And the last your mistake: malloc(X) allocates X bytes, so if you want to allocate memory for some array, you should use malloc(N * sizeof(T));, where N is the size of your array and T is its type. E.g.: if you wanna have int *a, you should do this: int *a = (int*) malloc(10 * sizeof(int));.
And now here's your code, fixed (as for me):
#include <stdio.h>
#include <stdlib.h>
int findFactors(int, int*);
int main(int argc, char **argv)
{
int numToFind, *factors = 0, cnt = 0;
do
{
printf("Enter a number to find the factors of: ");
scanf("%d", &numToFind);
} while (numToFind > 100);
cnt = findFactors(numToFind, factors);
printf("%d has %d factors.\n", numToFind, cnt);
return 0;
}
int findFactors(int N, int* factors)
{
if (!factors)
factors = (int*) malloc(N * sizeof(int));
int count = 0;
for (int i = 2; i < N; i++)
{
if (N % i == 0)
{
factors[count++] = i;
printf("%d is factor number #%d\n", i, count);
}
}
return count;
}
Note: do not forget to initialize your pointers any time (as i did). If you do want to call function, passing a pointer as its argument, you must be sure it has value of 0 at least before function call. Otherwise you will get run-time error.