A passed parameter was changed in the middle of the code without changing or manipulating the variable
I launched a C program with this command:
anonymous DELAI_ANONYME=O sanspm=O
The main function code is below:
int main(int argc, char *argv[])
{
EXEC SQL BEGIN DECLARE SECTION;
SQL100 qstrRefIndiv = {0};
int qiCheckIndiv = 0;
SQL20 qstrTrigStatus = {0};
EXEC SQL END DECLARE SECTION;
char strLogName[100] = {0};
char strRef[100] = {0};
int iNoCommit = 0;
int i = 0;
int iDelCase=0;
char strDelai[1];
char strSanspm[1];
strcpy(strDelai, "N");
strcpy(strSanspm, "N");
char selectcof[1000]= {0};
initscr();
bkg_init();
for(i=1; i<argc; i++)
{
refresh();
db_log_message (LL_INFO, "Iter Nbr= [%d]\n", i);
if(strcmp(argv[i],"NOCOMMIT")==0)
{
iNoCommit = 1;
}
if(strncmp(argv[i], "ref=", 4)==0)
{
strcpy(strRef,&argv[i][4]);
strcpy (qstrRefIndiv, strRef);
db_log_message (LL_INFO, "ref param= [%s]\n", qstrRefIndiv);
}
if(strncmp(argv[i], "DELAI_ANONYME=", 14)==0)
{
strcpy(strDelai,&argv[i][14]);
db_log_message (LL_INFO, "ref Delai= [%s]\n", strDelai);
}
if(strncmp(argv[i], "delcase=", 8)==0)
{
iDelCase=atoi(&argv[i][8]);
db_log_message (LL_INFO, "ref iDelCase= [%s]\n", iDelCase);
}
if(strncmp(argv[i], "sanspm=", 7)==0)
{
db_log_message (LL_INFO, "[sanspm] before ref Delai= [%s]\n", strDelai);
strcpy(strSanspm,&argv[i][7]);
db_log_message (LL_INFO, "ref strSanspm= [%s]\n", strSanspm);
db_log_message (LL_INFO, "[sanspm] after ref Delai= [%s]\n", strDelai);
}
}
db_log_message (LL_INFO, "ref Delai 1= [%s]\n", strDelai);
db_log_message (LL_INFO, "ref strSanspm 1= [%s]\n", strSanspm);
...
endwin();
return(0);
}
After checking the log file I see that the DELAI_ANONYME variable was changed in the middel of the for clause as shown in the logs after launching the program
Log:
[INFO ] [ 0.017] Iter Nbr= [1]
[INFO ] [ 0.000] ref Delai= [O]
[INFO ] [ 0.000] Iter Nbr= [2]
[INFO ] [ 0.000] [sanspm] before ref Delai= [O]
[INFO ] [ 0.000] ref strSanspm= [O]
[INFO ] [ 0.000] [sanspm] after ref Delai= []
[INFO ] [ 0.000] ref Delai 1= []
[INFO ] [ 0.000] ref strSanspm 1= [O]
When I changed the order of the parameters I got the below behavior with this command:
anonymous sanspm=O DELAI_ANONYME=O
I see the DELAI_ANONYME variable is OK but at the same time strSanspm variable is taking another character that is not initialized at the beginning 'OO'
Log:
[INFO ] [ 0.001] Iter Nbr= [1]
[INFO ] [ 0.000] [sanspm] before ref Delai= []
[INFO ] [ 0.000] ref strSanspm= [O]
[INFO ] [ 0.000] [sanspm] after ref Delai= []
[INFO ] [ 0.000] Iter Nbr= [2]
[INFO ] [ 0.000] ref Delai= [O]
[INFO ] [ 0.000] ref Delai 1= [O]
[INFO ] [ 0.000] ref strSanspm 1= [OO]
Related
I need to put the output of arr in global array because I need to use the array in main function. How can I initialize the array in global and I don't know the size of it ? any idea please?
globarr[]; // how to set the size here?
int *suma(int *output, int *arr)
{
*output = 0;
for (int i = 0; i < 100; i++) {
arr[i] = i;
*output += arr[i];
}
return arr;
}
void prose(){
int *by;
int output;
int arr[100];
by = suma(&output, arr);
for (ont i=0; i<output; i++) {
globarr[i] = n[i];
}
}
void main()
{
prose();
// here I need to use the values of globarr
}
I need to put the output of arr in global array
The only reason you might need to do that would be that some external authority you are bound to obey placed such an arbitrary, unnatural requirement.
It is possible to write conforming C code for any task, using only the C standard library, that does not rely on any global variables other than those few provided by the standard library itself.
because I need to use the array in main function. How can I initialize the array in global and I don't know the size of it ?
You cannot. The size of an array declared at file scope must be an integer constant expression, which means, among other things, that it must be computable at compile time.
any idea please?
You have two main alternatives:
Choose an upper bound on the size your program will support, and declare an array large enough for that. Make the program abort if otherwise it would try to use more elements of the array than are available.
Use a dynamically allocated space instead of a (declared) array.
Use function parameters and return values not global variables
long long suma(int **arr, size_t size)
{
long long output = 0;
*arr = malloc(size * sizeof(**arr));
if(*arr)
{
for (size_t i = 0; i < size; i++)
{
(*arr)[i] = i;
output += (*arr)[i];
}
}
return output;
}
#define SIZE 100
void main(void)
{
int *array;
long long output = suma(&array, SIZE);
printf("Sum of elements = %lld\n", output);
/* you can use the array */
if(array)
{
for(size_t i = 0; i < SIZE; i++)
{
printf("[%3zu]=%d%s", i, array[i], ((i + 1) % 10) ? ",\t" : "\n");
}
}
free(array);
}
https://godbolt.org/z/EPdxfPzoq
Output:
Sum of elements = 4950
[ 0]=0, [ 1]=1, [ 2]=2, [ 3]=3, [ 4]=4, [ 5]=5, [ 6]=6, [ 7]=7, [ 8]=8, [ 9]=9
[ 10]=10, [ 11]=11, [ 12]=12, [ 13]=13, [ 14]=14, [ 15]=15, [ 16]=16, [ 17]=17, [ 18]=18, [ 19]=19
[ 20]=20, [ 21]=21, [ 22]=22, [ 23]=23, [ 24]=24, [ 25]=25, [ 26]=26, [ 27]=27, [ 28]=28, [ 29]=29
[ 30]=30, [ 31]=31, [ 32]=32, [ 33]=33, [ 34]=34, [ 35]=35, [ 36]=36, [ 37]=37, [ 38]=38, [ 39]=39
[ 40]=40, [ 41]=41, [ 42]=42, [ 43]=43, [ 44]=44, [ 45]=45, [ 46]=46, [ 47]=47, [ 48]=48, [ 49]=49
[ 50]=50, [ 51]=51, [ 52]=52, [ 53]=53, [ 54]=54, [ 55]=55, [ 56]=56, [ 57]=57, [ 58]=58, [ 59]=59
[ 60]=60, [ 61]=61, [ 62]=62, [ 63]=63, [ 64]=64, [ 65]=65, [ 66]=66, [ 67]=67, [ 68]=68, [ 69]=69
[ 70]=70, [ 71]=71, [ 72]=72, [ 73]=73, [ 74]=74, [ 75]=75, [ 76]=76, [ 77]=77, [ 78]=78, [ 79]=79
[ 80]=80, [ 81]=81, [ 82]=82, [ 83]=83, [ 84]=84, [ 85]=85, [ 86]=86, [ 87]=87, [ 88]=88, [ 89]=89
[ 90]=90, [ 91]=91, [ 92]=92, [ 93]=93, [ 94]=94, [ 95]=95, [ 96]=96, [ 97]=97, [ 98]=98, [ 99]=99
Let me preface by saying I'm a total novice at perl.
I need to modify rules on a mail system. I can access the rules as an array and I believe the array contains subarrays. I need to modify one particular element and preserve the rest. My problem is I'm confused as to what the array type really is and how to consistently access the elements.
There may be more than one set of rules, but I'm only interested in processing rules with a priority of '1', which is $Rule[0]. Within $Rule[3] I need to parse the addresses.
use strict;
use Data::Dumper qw(Dumper);
my $Rules=$cli->GetAccountMailRules($account);
print Dumper \#$Rules;
foreach my $Rule (#$Rules) {
if($Rule->[0]=~/1/) {
my $pri=$Rule->[0];
my $type=$Rule->[1];
my $auto=$Rule->[2];
my $actions=$Rule->[3];
my $action1;
my $auto1;
my $auto2;
my #newRule;
my $oldDest;
print "\n";
print "Priority:\n";
print Dumper \$pri;
print "\n";
print "Rule Type:\n";
print Dumper \$type;
print "\n";
print "Forward Auto?:\n";
print Dumper \$auto;
print "\n";
print "Actions:\n";
print Dumper \$actions;
print "\n";
foreach my $ax (#$actions) {
$action1=$ax->[0];
$oldDest=$ax->[1];
}
my #addresses=split /[;,]|\\e/, $oldDest;
my #dests = grep(/corp.com|corp1.com|corp2.com|corp3.com/, #addresses);
my $newDest = join(",", #dests);
if (#$auto) {
foreach my $au (#$auto) {
$auto1=$au->[0];
$auto2=$au->[1];
}
#newRule=(
[ $pri, $type,
[[$auto1,$auto2]],
[[$action1,$newDest]]
]
);
} else {
#newRule=(
[ $pri, $type,
[],
[[$action1,$newDest]]
]
);
}
}
}
}
Output thusly:
# perl removeRules.pl
$VAR1 = [
[
'1',
'#Redirect',
[
[
'Human Generated',
'---'
]
],
[
[
'Mirror to',
'test10#corp.com\\etest10#gmail.com\\etest10#corp1.com'
]
]
]
];
Priority:
$VAR1 = \'1';
Rule Type:
$VAR1 = \'#Redirect';
Forward Auto?:
$VAR1 = \[
[
'Human Generated',
'---'
]
];
Actions:
$VAR1 = \[
[
'Mirror to',
'test10#corp.com\\etest10#gmail.com\\etest10#corp1.com'
]
];
The problem I'm running into is there is an option within $actions to discard emails after forwarding, which introduces new elements (or subarray?) into $actions:
# perl removeRules.pl
$VAR1 = [
[
'1',
'#Redirect',
[
[
'Human Generated',
'---'
]
],
[
[
'Mirror to',
'test10#corp.com\\etest10#gmail.com\\etest10#corp1.com'
],
[ <---- Begin new elements
'Discard',
'---'
] <---- End new elements
]
]
];
Priority:
$VAR1 = \'1';
Rule Type:
$VAR1 = \'#Redirect';
Forward Auto?:
$VAR1 = \[
[
'Human Generated',
'---'
]
];
Actions:
$VAR1 = \[
[
'Mirror to',
'test10#corp.com\\etest10#gmail.com\\etest10#corp1.com'
],
[
'Discard',
'---'
]
];
I tried testing to see if they can be referenced as additional elements in $actions but it throws off the index.
my $action2;
my $action3;
print "Actions:\n";
print Dumper \$actions;
print "\n";
foreach my $ax (#$actions) {
$action1=$ax->[0];
$oldDest=$ax->[1];
$action2=$ax->[2];
$action3=$ax->[3];
}
print " action1 $action1\n";
print " oldDest $oldDest\n";
print " action2 $action2\n";
print " action3 $action3\n";
Output:
Actions:
$VAR1 = \[
[
'Mirror to',
'test10#corp.com\\etest10#gmail.com\\etest10#corp1.com'
],
[
'Discard',
'---'
]
];
action1 Discard
oldDest ---
Use of uninitialized value $action2 in concatenation (.) or string at removeRules.pl line 107, <GEN0> line 4.
action2
Use of uninitialized value $action3 in concatenation (.) or string at removeRules.pl line 108, <GEN0> line 4.
action3
Thank you in advance.
Using this:
[
[
'Mirror to',
'test10#corp.com\\etest10#gmail.com\\etest10#corp1.com'
],
[
'Discard',
'---'
]
]
This is a reference to an array (the outer [..]) that has two items. Each item is again a reference to an array.
First item (position 0 of outer array reference) is
[
'Mirror to',
'test10#corp.com\\etest10#gmail.com\\etest10#corp1.com'
],
and second (position 1) is:
[
'Discard',
'---'
]
If $ractions is this outer array, then the above two items are respectively under $ractions->[0] and $ractions->[1].
Since they are both an array reference again you can access their items using the same construct, or using a Perl property, you can remove the second array.
In short:
'Mirror to' can be accessed by $ractions->[0]->[0] or shorter $ractions->[0][0]
'test10#corp.com\etest10#gmail.com\etest10#corp1.com' can be accessed by $ractions->[0]->[1]
'Discard' can be accessed by $ractions->[1]->[0]
'---' can be accessed by $ractions->[1]->[1]
Be aware however that $VAR1 = \[ shows that you have a reference over a reference. So you will need an extra step of derefencing:
DB<1> use Data::Dumper;
DB<2> #a=(1,2)
DB<3> print Data::Dumper::Dumper(#a);
$VAR1 = 1;
$VAR2 = 2;
DB<4> print Data::Dumper::Dumper(\#a);
$VAR1 = [
1,
2
];
DB<5> print Data::Dumper::Dumper(\\#a);
$VAR1 = \[
1,
2
];
PS: do not use corp.com or anything like that when you need to obfuscate domain names. See guidance in RFC2606 or TL;DR: use example.com
Upon the aggregate function, the output i have got is of the form :-
> [ { DescriptionArray:
[ 'Des1',
'Des2',
'Des3',
'Des4' ],
PicArray:
[ 'Pic1.jpeg',
'Pic2.jpeg',
'Pic3.jpeg',
'Pic4.jpeg' ] } ]
But, i want the output to be of the form :-
>[ { DescriptionArray:
[
['Des1'],
['Des2'],
['Des3'],
['Des4' ]
],PicArray:
[
['Pic1.jpeg'],
['Pic2.jpeg'],
['Pic3.jpeg'],
['Pic4.jpeg']
] } ]
The aggregate function of mine is as follows:-
>User.aggregate([
{
"$project": {
"_id": 0,
"DescriptionArray": {
"$reduce": {
"input": "$services.description",
"initialValue": [],
"in": {
"$concatArrays": [
"$$this",
"$$value"
]
}
}
},
"PicArray": {
"$reduce": {
"input": "$services.badpic",
"initialValue": [],
"in": {
"$concatArrays": [
"$$this",
"$$value"
]
}
}
}
}
}
])
The schema of my database is as follows:-
> var serviceSchema = new mongoose.Schema({
description:[String],
pic:[String]
})
Is there any way, i can get the output of my desired format?
I'm working on a project that's using the cmocka framework. The cmocka homepage states
Test fixtures are setup and teardown functions that can be shared across multiple test cases to provide common functions that prepare the test environment and destroy it afterwards.
However, none of the docs I've read explain how the fixture system works.
If I'm running my tests with code that looks like this
int main(void) {
const struct CMUnitTest license_tests[] = {
cmocka_unit_test(test_setup),
cmocka_unit_test(test_null_app),
cmocka_unit_test(test_null_name),
};
return cmocka_run_group_tests(license_tests, NULL, NULL);
}
How/where can I instruct cmocka to run setup/tear down fixtures and what features (if any) does cmocka have for letting me access things created in said fixtures?
Here is a template unit testing file that you can reuse in your project. It tackles all your requirements
#include <stdio.h>
#include <cmocka.h>
#include "mylib.h"
// Include here all your mocked functions, see below
#include "testmocks.c"
typedef struct {
mylibobj_t* mylibobj;
} teststate_t;
/**
* This is run once before all group tests
*/
static int groupSetup (void** state) {
teststate_t* teststate = calloc(1, sizeof(teststate_t));
*state = teststate;
return 0;
}
/**
* This is run once after all group tests
*/
static int groupTeardown (void** state) {
teststate_t* teststate = *state;
free(teststate);
return 0;
}
/**
* This is run once before one given test
*/
static int testSetup (void** state) {
teststate_t* teststate = *state;
//Maybe instantiate mylibobj?
return 0;
}
/**
* This is run once after one given test
*/
static int testTeardown (void** state) {
return 0;
}
/**
* This test will success with these options
*/
void mylib_setTime_s0 (void** state) {
teststate_t* teststate = *state;
// Do your testing stuff
}
/**
* This test will fail with these options
*/
void mylib_setTime_f0 (void** state) {
teststate_t* teststate = *state;
// Do your testing stuff
}
int main (void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(mylib_setTime_s0, testSetup, testTeardown),
cmocka_unit_test_setup_teardown(mylib_setTime_f0, testSetup, testTeardown),
};
return cmocka_run_group_tests(tests, groupSetup, groupTeardown);
}
The testmocks.c exists just for code organization, and may hold 0 to N pairs of mocked functions as
#define MOCKBYPASS -7337
mylib_status_t __real_inner_function (char* id);
mylib_status_t __wrap_inner_function (char* id) {
int mock = mock();
if(mock == MOCKBYPASS)
return __real_inner_function(id);
else
return mock;
}
...
Remember that gcc compilation tricks are a must for these mocks to work correctly
Those two NULL's you are passing to cmocka_run_group_tests function should, be group_setup and group_teardown functions, both type CMFixtureFunction - if You want to utilize
setup and teardown functions that can be shared across multiple test cases
in cmocka called test fixtures. As documentation for this function states.
Then shared (void** state) is accessible in each test. It can be used as in example below:
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <cmocka.h>
#define GREETINGS "one string to rule them all, One string to find them, "\
"one string to bring them all and in the darkness bind them"
#define PRECIOUSS_T1 "Three strings for the Elven-kings under the sky,"
#define PRECIOUSS_T2 "even for the Dwarf-lords in halls of stone,"
#define PRECIOUSS_T3 "Nine for Mortal Men, doomed to die,"
#define PRECIOUSS_T4 "One for the Dark Lord on his dark throne"
#define PRECIOUSS_T5 "In the Land of Mordor where the Shadows lie."
#define PRECIOUSS_T6 "One string to rule them all, One Ring to find them,"
#define PRECIOUSS_T7 "One string to bring them all and in the darkness bind them."
#define PRECIOUSS_T8 "In the Land of Mordor where the Shadows lie."
#define OOPS "Not quite what I expected"
#define T(X) PRECIOUSS_T##X
#define FOO(X) case X: strncpy(lots->memory, T(X), sizeof(T(X))); break;
#define SPR_FOO(X) case X: assert_string_equal(T(X), lots->memory); break;
typedef struct {
int line;
char * memory;
} lord_of_the_strings_t;
static int gr_setup(void **state) {
/* this is run once before all group tests */
lord_of_the_strings_t *book = malloc(sizeof(*book));
if (book == NULL)
return -1;
book->memory = malloc(sizeof(GREETINGS));
if (book->memory == NULL) {
return -1;
}
strncpy(book->memory, GREETINGS, sizeof(GREETINGS));
assert_string_equal(book->memory, GREETINGS);
*state = book;
return 0;
}
static int gr_teardown(void **state) {
/* this is run once after all group tests */
lord_of_the_strings_t *lots = *state;
free(lots->memory);
free(lots);
return 0;
}
static int ve_teardown(void **state) {
/* this is run before some single tests */
lord_of_the_strings_t *lots = *state;
lots->line = 42;
return 0;
}
static int ve_setup(void **state) {
/* this is run after some single tests */
static int setup_counter = 0;
lord_of_the_strings_t *lots = *state;
lots->line = ++setup_counter;
switch (setup_counter) {
FOO(1)
FOO(2)
FOO(3)
FOO(4)
FOO(5)
FOO(6)
FOO(7)
FOO(8)
default:
strncpy(lots->memory, OOPS, sizeof(OOPS));
};
return 0;
}
static void failing_test(void **state) {
assert_false("Sorry");
}
static void line_aware_test(void **state) {
lord_of_the_strings_t *lots = *state;
printf(" (shared) between tests, line=%d memory=%s\n", lots->line, lots->memory);
}
static void passing_test(void **state) {
}
static void string_recite_test(void **state) {
static int line_counter = 0;
lord_of_the_strings_t *lots = *state;
if (lots->line < 9)
assert_true(line_counter+1 == lots->line);
switch (++line_counter) {
SPR_FOO(1)
SPR_FOO(2)
SPR_FOO(3)
SPR_FOO(4)
SPR_FOO(5)
SPR_FOO(6)
SPR_FOO(7)
SPR_FOO(8)
default:
line_counter = 0;
}
}
int main(void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(passing_test),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test(line_aware_test),
cmocka_unit_test(line_aware_test),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test(line_aware_test),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test(line_aware_test),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test_setup_teardown(string_recite_test, ve_setup, ve_teardown),
cmocka_unit_test(failing_test),
};
return cmocka_run_group_tests(tests, gr_setup, gr_teardown);
}
Which should yield output like
[==========] Running 21 test(s).
[ RUN ] passing_test
[ OK ] passing_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] line_aware_test
(shared) between tests, line=42 memory=Nine for Mortal Men, doomed to die,
[ OK ] line_aware_test
[ RUN ] line_aware_test
(shared) between tests, line=42 memory=Nine for Mortal Men, doomed to die,
[ OK ] line_aware_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] line_aware_test
(shared) between tests, line=42 memory=One string to rule them all, One Ring to find them,
[ OK ] line_aware_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] string_recite_test
[ OK ] string_recite_test
[ RUN ] string_recite_test
[ ERROR ] --- "Three strings for the Elven-kings under the sky," != "Not quite what I expected"
[ LINE ] --- aa.c:100: error: Failure!
[ FAILED ] string_recite_test
[ RUN ] string_recite_test
[ ERROR ] --- "even for the Dwarf-lords in halls of stone," != "Not quite what I expected"
[ LINE ] --- aa.c:101: error: Failure!
[ FAILED ] string_recite_test
[ RUN ] line_aware_test
(shared) between tests, line=42 memory=Not quite what I expected
[ OK ] line_aware_test
[ RUN ] string_recite_test
[ ERROR ] --- "Nine for Mortal Men, doomed to die," != "Not quite what I expected"
[ LINE ] --- aa.c:102: error: Failure!
[ FAILED ] string_recite_test
[ RUN ] string_recite_test
[ ERROR ] --- "One for the Dark Lord on his dark throne" != "Not quite what I expected"
[ LINE ] --- aa.c:103: error: Failure!
[ FAILED ] string_recite_test
[ RUN ] string_recite_test
[ ERROR ] --- "In the Land of Mordor where the Shadows lie." != "Not quite what I expected"
[ LINE ] --- aa.c:104: error: Failure!
[ FAILED ] string_recite_test
[ RUN ] string_recite_test
[ ERROR ] --- "One string to rule them all, One Ring to find them," != "Not quite what I expected"
[ LINE ] --- aa.c:105: error: Failure!
[ FAILED ] string_recite_test
[ RUN ] failing_test
[ ERROR ] --- "Sorry"
[ LINE ] --- aa.c:79: error: Failure!
[ FAILED ] failing_test
[==========] 21 test(s) run.
[ PASSED ] 14 test(s).
[ FAILED ] 7 test(s), listed below:
[ FAILED ] string_recite_test
[ FAILED ] string_recite_test
[ FAILED ] string_recite_test
[ FAILED ] string_recite_test
[ FAILED ] string_recite_test
[ FAILED ] string_recite_test
[ FAILED ] failing_test
7 FAILED TEST(S)
I have the following code, but i can't figure out why the error:PANIC=runtime error: index out of range is happening
type Board struct {
Tboard [9]string
Player1 Player
Player2 Player
}
func makeBoard() *Board {
b := &Board{Tboard: [9]string{}}
for x := 0; x < len(b.Tboard); x++ {
b.Tboard[x] = E // E = "[ ]"
fmt.Println(b.Tboard[x])
}
fmt.Println(len(b.Tboard)) // => 9
fmt.Print("Error: ")
fmt.Println(b) // => Error: %!v(PANIC=runtime error: index out of range)
fmt.Println(b.Tboard) // => [[ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]]
return b
}