i have some problems sorting a struct field and cannot find the answer why this is happening...
The Error message when i run the program says "Memory access error (German: Speicherzugriffsfehler (Speicherabzug geschrieben)). The error only comes whenever i try the proceed one of the following lines in the bubblesort:
x= *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;
I have the feeling that i might have to save memory with malloc() or calloc() at some point, but i don't know how to use this,yet...
Thank you for your help!
Best regards
kazimir
You can see the the entire code below:
#include <stdio.h>
#include <string.h>
typedef struct
{
char* nation;
int goals_scored;
int goals_conceded;
} Team;
typedef struct
{
Team* t1;
Team* t2;
int goals_t1;
int goals_t2;
}Spiel;
void ergebnis_eintragen(Spiel s)
{
s.t1->goals_scored = s.goals_t1;
s.t2->goals_scored = s.goals_t2;
s.t1->goals_conceded = s.goals_t2;
s.t2->goals_conceded = s.goals_t1;
}
void ausgabe (Team* mannschaften[8])
{
Team x;
int m=8;
int vertauscht;
do
{
vertauscht=0;
for (int i=0;i<8;i++)
{
if (mannschaften[i]->goals_scored<mannschaften[i+1]->goals_scored)
{
x= *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;
}
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored||mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
{
x = *mannschaften[i];
*mannschaften[i]=*mannschaften[i+1];
*mannschaften[i+1]=x;
vertauscht=1;
}
}
m-=1;
}
while (m>1 && vertauscht);
for (int i=0;i<8;i++)
printf("\nNation: %s\nTore: %d\nGegentore: %d\n",mannschaften[i]->nation,mannschaften[i]->goals_scored,mannschaften[i]->goals_conceded);
}
int main (void)
{
Team t1={"Kroatien",0,0};
Team t2={"Brasilien",0,0};
Team t3={"Niederlande",0,0};
Team t4={"Argentinien",0,0};
Team t5={"Marokko",0,0};
Team t6={"Portugal",0,0};
Team t7={"England",0,0};
Team t8={"Frankreich",0,0};
Spiel s1={&t1,&t2,5,3};
Spiel s2={&t3,&t4,5,6};
Spiel s3={&t5,&t6,1,0};
Spiel s4={&t7,&t8,1,2};
Spiel s5={&t4,&t1,3,0};
Spiel s6={&t8,&t5,2,0};
Spiel s7={&t1,&t5,2,1};
Spiel s8={&t4,&t8,7,5};
Team* ptr_team[8];
ptr_team[0] = &t1;
ptr_team[1] = &t2;
ptr_team[2] = &t3;
ptr_team[3] = &t4;
ptr_team[4] = &t5;
ptr_team[5] = &t6;
ptr_team[6] = &t7;
ptr_team[7] = &t8;
ergebnis_eintragen(s1);
ergebnis_eintragen(s2);
ergebnis_eintragen(s3);
ergebnis_eintragen(s4);
ergebnis_eintragen(s5);
ergebnis_eintragen(s6);
ergebnis_eintragen(s7);
ergebnis_eintragen(s8);
ausgabe(&ptr_team[0]);
}
I already tried looking for a simular question, but couldn't find anything...
In the for loop
for (int i=0;i<8;i++)
{
if (mannschaften[i]->goals_scored<mannschaften[i+1]->goals_scored)
when i is equal to 7 then expressions like this
mannschaften[i+1]->goals_scored)
access memory outside the array ptr_team defined in main.
You could write your loop like for example
for (int i=1;i<8;i++)
{
if (mannschaften[i-1]->goals_scored<mannschaften[i]->goals_scored)
//...
Also it seems in this if statement
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored||mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
you mean the logical operator && instead of the logical operator ||
else if (mannschaften[i]->goals_scored==mannschaften[i+1]->goals_scored && mannschaften[i]->goals_conceded>mannschaften[i+1]->goals_conceded)
Using the variable m as is in the do-while loop does not make a great sense. It is enough to use the variable vertauscht
do
{
//...
} while ( vertauscht);
And it is a bad idea to use magic numbers like 8.
You could declare your function like
void ausgabe (Team* mannschaften[], size_t n );
and call it at least like
ausgabe( ptr_team, 8 );
Then within the function you should use the variable n instead of the magic number 8 as for example
for ( size_t i = 1;i < n;i++ )
Otherwise you will need to change your function each time when the size of the passed array will be changed.
You should always write a more general function.
Pay attention to that your program will look much better and will be more readable if you will use English words for identifiers.
Related
I'm currently working on sorting algo. project. We have a limited amount of operations we can use and we are allowed to only use 2 stacks. One of the operations is called pushA and pushB.
The push operation is supposed to push the top value of one stack to the top of the other stack.
This is my current implementation:
typedef struct stack
{
struct stack *prev;
int data;
int size;
struct stack *next;
} t_list_a, t_list_b;
int main(int argc, char *argv[])
{
t_list_a *tail_a;
if (!(ft_isdigit(argv, argc)) || !(checkDups(argv, argc)))
return (1);
tail_a = createList(tail_a, argv, argc);
}
t_list_a *createList(t_list_a *tail_a, char **argv, int argc)
{
int i;
tail_a = firstNode_A(ft_atoi(argv[argc - 1]));
i = argc - 2;
while (i > 0)
{
tail_a = addEnd_A(tail_a, ft_atoi(argv[i]));
i--;
}
tail_a->size = argc;
return (tail_a);
}
firstNode_A and addEnd just either creates the first node or adds a node to the other
Now to the issue
void pushB(t_list_a *tail_a, t_list_b *tail_b)
{
if (!tail_b)
tail_b = firstNode_B(tail_a->data);
else
tail_b = addEnd_B(tail_b, tail_a->data);
tail_a = delLast_A(tail_a);
}
ISSUE:
If I access tail_b.data it's now accessible and tail_a is updated accordingly. However, If I try to declare a t_list_b *tail_b in my main it's not accessible.
I do understand the issue that the struct ptr to the struct is not accessible outside the local scope. However, I don't know how to remedy it.
I've tried creating a double ptr inside the struct and outside and giving the address of tail_a and tail_b to the ptr.
I was thinking to create an array of structs.
P.S:
I'm a bit lost, also this is my second time asking a question so I expect there are some flaws in "how I ask". I would appreciate it a lot if you could indicate how I could ask my questions better so I can learn. Thank you.
Let's say that I declare a C struct called foo, which has an int field called bar and a char * called baz.
How do I use the Cmocka expect_ and check_expected macros to check that the structure passed was correct and both fields have the expected values? If there is an example in the documentation, I missed it.
[Update] Perhaps I can use expect_check()? But I can't find an example :-(
Use expect_memory(...) and check_expected(...):
Example:
I assume you have a function under test fut which calls a subfunction subfunc. Your struct looks like this:
typedef struct foo_s {
int bar;
int baz;
} foo;
And your test driving function could look like this:
void test(void **state) {
foo myfoo = {
.bar = 42,
.baz = 13,
};
expect_memory(subfunc, param, &myfoo, sizeof(foo));
fut();
}
And the subfunctions could look like this:
void subfunc(foo *param){
check_expected(param);
}
Comparing the memory of the struct might work in most cases, however if your compiler puts some filler bytes in there, you have some bytes which you have no controll over and might have random values. This means that your test might not alway yield the same result, which can lead to very annoying debugging session.
For example if you have a struct like this:
typedef struct {
uint8_t c;
uint32_t i;
} tSomeStruct
You might think that the c and i are put right next to each other and sizeof( tSomeStruct ) returns 5. However if you try this out you would be surprised that it is more likely that sizeof( tSomeStruct ) actually returns 8. This is because of the mentioned filler bytes. You do not know what the values of these other bytes are. You can work around this by memsetting your structs to 0 before using them, however this is a little bit hacky and does not work in every case.
To compare structs in a clean way cmocka you can use expect_check( ... ) and check_expected( ... ). This gives you the possibility to write your own comparisson function.
Here is an example on how to use this ( Modified this example: Cmocka Gitlab )
typedef struct {
char c;
int i;
} tSomeStruct;
void mock_function( tSomeStruct* param )
{
check_expected(param)
}
/* return 1 = true, return 0 = false */
int my_int_equal_check(const LargestIntegralType value,
const LargestIntegralType check_value_data)
{
tSomeStruct* cast_value = ( tSomeStruct* ) value;
tSomeStruct* cast_check_value_data = ( tSomeStruct* ) check_value_data;
if ( ( cast_value->c == cast_check_value_data->c )
&& ( cast_value->i == cast_check_value_data->i ) ) {
return 1;
}
return 0;
}
void mytest(void **state)
{
tSomeStruct struct = {
.c = 'c',
.i = 'i',
}
expect_check(mock_function, param, my_int_equal_check, &struct);
}
I am not sure however if this is possible, if you do not pass your struct as a pointer to your function, as the check function only takes LargestIntegralType.
I recently found out that you can use the struct members inside the check_expected and expect_value:
typedef struct
{
int a;
float b;
} SomeStruct_t;
void mocked_function(SomeStruct_t* s)
{
check_expected(s->a);
check_expected(s->b);
}
void someTest(void **state)
{
expect_value(mocked_function, s->a, 3);
expect_value(mocked_function, s->b, 7.2);
// ...
}
Here's my code. It works when I comment out the "luetut" variable.
But when I compile as follows, I get segmentation fault when the program should print the variables. What sense does this make? When I try to make a debug build, something totally weird shows up (multiple definition of this and that).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct rakenne
{
int luku;
float liukuluku;
char* mjono;
} Rakenne;
int main(int argc, char *argv[])
{
int luetut = 0;
Rakenne palikka;
// Rakenne palikka, *palikkaosoitin;
// palikkaosoitin = &palikka;
// while(luetut < 1)
// {
printf("Anna luku:\n");
scanf("%d", &palikka.luku);
// } luetut = 0;
// while(luetut < 1)
// {
printf("Anna liukuluku:\n");
scanf("%f", &palikka.liukuluku);
// } luetut = 0;
printf("Anna merkkijono:\n");
scanf("%s", palikka.mjono);
printf("%i\t%.3f\t%s\n", palikka.luku, palikka.liukuluku, palikka.mjono);
return 0;
}
So, is my gcc compiler broken or what could be the problem?
scanf("%s", palikka.mjono);
You didn't make mjono point to anything so writing to it is of course illegal - undefined behavior. Doing something like this leads to erratic behavior: the program "works" or "fails" for no apparent reason.
So, is my gcc compiler broken or what could be the problem
It's rarely constructive to think the tools you are using are the problem.
Expanding on cnicutars answer, the fix would be to allocate some memory for palikka.mjono.
Something like this:
#define SIZE 40 // or whatever you need.
palikka.mjono = malloc( sizeof(char) * SIZE );
Then later don't forget to free that memory:
free( palikka.mjono );
Or if you know what the maximum size of your strings will be, just define your structure as:
typedef struct rakenne
{
int luku;
float liukuluku;
char mjono[SIZE];
} Rakenne;
I am very much stuck in the following issue. Any help is very much appreciated!
Basically I have a program wich contains an array of structs and I am getting a segmentation error when I call an external function. The error only happens when I have more than 170 items on the array being passed.
Nothing on the function is processed. The program stops exactly when accessing the function.
Is there a limit for the size of the parameters that are passed to external functions?
Main.c
struct ratingObj {
int uid;
int mid;
double rating;
};
void *FunctionLib; /* Handle to shared lib file */
void (*Function)(); /* Pointer to loaded routine */
const char *dlError; /* Pointer to error string */
int main( int argc, char * argv[]){
// ... some code ...
asprintf(&query, "select mid, rating "
"from %s "
"where uid=%d "
"order by rand()", itable, uid);
if (mysql_query(conn2, query)) {
fprintf(stderr, "%s\n", mysql_error(conn2));
exit(1);
}
res2 = mysql_store_result(conn2);
int movieCount = mysql_num_rows(res2);
// withhold is a variable that defines a percentage of the entries
// to be used for calculations (generally 20%)
int listSize = round((movieCount * ((double)withhold/100)));
struct ratingObj moviesToRate[listSize];
int mvCount = 0;
int count =0;
while ((row2 = mysql_fetch_row(res2)) != NULL){
if(count<(movieCount-listSize)){
// adds to another table
}else{
moviesToRate[mvCount].uid = uid;
moviesToRate[mvCount].mid = atoi(row2[0]);
moviesToRate[mvCount].rating = 0.0;
mvCount++;
}
count++;
}
// ... more code ...
FunctionLib = dlopen("library.so", RTLD_LAZY);
dlError = dlerror();
if( dlError ) exit(1);
Function = dlsym( FunctionLib, "getResults");
dlError = dlerror();
(*Function)( moviesToRate, listSize );
// .. more code
}
library.c
struct ratingObj {
int uid;
int mid;
double rating;
};
typedef struct ratingObj ratingObj;
void getResults(struct ratingObj *moviesToRate, int listSize);
void getResults(struct ratingObj *moviesToRate, int listSize){
// ... more code
}
You are likely blowing up the stack. Move the array to outside of the function, i.e. from auto to static land.
Another option is that the // ... more code - array gets populated... part is corrupting the stack.
Edit 0:
After you posted more code - you are using C99 variable sized array on the stack - Bad IdeaTM. Think what happens when your data set grows to thousands, or millions, of records. Switch to dynamic memory allocation, see malloc(3).
You don't show us what listsize is, but I suppose it is a variable and not a constant.
What you are using are variable length arrays, VLA. These are a bit dangerous if they are too large since they usually allocated on the stack.
To work around that you can allocate such a beast dynamically
struct ratingObj (*movies)[listSize] = malloc(sizeof(*movies));
// ...
free(movies);
You'd then have in mind though that movies then is a pointer to array, so you have to reference with one * more than before.
Another, more classical C version would be
struct ratingObj * movies = malloc(sizeof(*movies)*listsize);
// ...
free(movies);
I'd like to know if someone can explain me the solution to this problem:
the code is:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int c[20];
int n;
} t_coda;
t_coda coda;
void init(t_coda *coda) {
coda->n = 0;
}
void add(t_coda *coda, int x) {
if (coda->n < 20)
coda->c[(coda->n)++] = x;
}
main() {
init(&coda);
coda->n=1;
coda->c[0]=2;
add(&coda,3);
add(&coda,4);
}
And I need to know the corresponding instruction of: coda->n = 0; and coda->c[(coda->n)++] = x; in simplesem (an assembly-like semantic);
The solution is:
set D[D[0]+3]+20, 0
for the first question
and:
set D[D[0]+3]+D[D[D[0]+3]+20], D[D[0]+4]
set D[D[0]+3]+20, D[D[D[0]+3]+20] + 1
for the second one;
D is the Data stack, and D[0] return the value contained in the 0-cell of the data
Thank you
I would guess that...
D[0]+3 is a reference to the address of coda (the *coda in the function call)
D[D[0]+3] is a lookup of the data at the address where coda is stored
D[D[0]+3]+20 is an offset of 20 from where coda begins, thus moving past coda->c (which is 20 items) to get to coda->n.
That should help you to understand the first one; the same ideas can be extended to the second.