gpt4 book ai didi

c - 在 glib 中向 gprtarray 添加结构元素,但无法检索

转载 作者:行者123 更新时间:2023-11-30 17:48:39 25 4
gpt4 key购买 nike

我试图从一组 M^2 连续整数中生成 M 个整数的组合,然后根据一些(当前不相关的)标准排除一些组合,并尝试将它们动态存储在内存中,以便我能够以便稍后访问它们。

这些组合是使用 GNU 科学库 (docs here) 中的“gsl_combination”结构生成的。正如您从下面的代码片段中看到的,组合生成正常(并且根据需要排除)。

然后我需要将每个组合结构对象附加到内存中以供以后检索。我正在尝试使用 glib 指针数组来执行此操作。

代码:gptrwierd.c

#include <glib.h>
#include <gsl/gsl_combination.h>

//Hardcoded the size of the rigol lattice
//MUST BE ODD !!!
#define M 3

//Returns GSL_SUCCESS if the combination contains a forbidden site, otherwise returns GSL_FAILURE
int
is_forbidden (const gsl_combination * test)
{
int i, forbidden = GSL_FAILURE; //Not forbidden by default
size_t k = test->k;
size_t *data = test->data;
int halfway = ((M * M - 1) / 2); //The halfway point in the 2D grid

...
... //Some code for updating 'forbidden'
...
return forbidden;
}


#undef __FUNCT__
#define __FUNCT__ "main"
int
main (int argc, char **argv)
{
long count, istride;
//Generate the basis states
gsl_combination *c = gsl_combination_calloc (M * M, M);
//An array that will contain selected basis vectors.
GPtrArray *basis = g_ptr_array_new ();
count = 0;
do
{
//c is the ith combination of M integers from M^2 integers
//Get all the non forbidden elements
if (is_forbidden (c) == GSL_FAILURE)
{ //If the site is NOT forbidden, append c to basis
g_ptr_array_add (basis, c); //Appends c to basis
{
printf ("count %ld {", count);
gsl_combination_fprintf (stdout,
g_ptr_array_index (basis, count), " %u");
printf (" }\n");
}
count++;
}
}
while (gsl_combination_next (c) == GSL_SUCCESS);
printf("\n\n");
//Now, access each basis element from GArray
for (istride = 0; istride < basis->len; istride++)
{
printf ("istride %ld {", istride);
gsl_combination_fprintf (stdout, g_ptr_array_index (basis, istride),
" %u");
printf (" }\n");

}

gsl_combination_free (c);
g_ptr_array_free (basis, TRUE);
return 0;
}

生成文件:

            GSL_FLAGS  = gsl-config --cflags
GLIB_LOC = pkg-config --cflags --libs glib-2.0
CFLAGS = -Wall -O3 `$(GSL_FLAGS)` `$(GLIB_LOC)`

GSL_LIBS = gsl-config --libs-without-cblas
GLIB_LIBS = pkg-config --libs glib-2.0



gptrwierd:
gcc $(CFLAGS) -c gptrwierd.c
gcc -o $@ gptrwierd.o -lgsl -lgslcblas -lm `$(GLIB_LIBS)`

allclean: clean
${RM} gptrwierd *.dat

编译和运行就这样完成了(M硬编码为3):

$make gptrwierd
gcc -Wall -O3 `gsl-config --cflags` `pkg-config --cflags --libs glib-2.0` -c gptrwierd.c
gcc -o gptrwierd gptrwierd.o -lgsl -lgslcblas -lm `pkg-config --libs glib-2.0`
$./gptrwierd > out.dat

输出文件的内容粘贴在下面:

count 0 { 1 2 3 }
count 1 { 1 2 4 }
count 2 { 1 2 6 }
count 3 { 1 2 7 }
count 4 { 1 2 8 }
count 5 { 1 3 4 }
count 6 { 1 3 6 }
count 7 { 1 3 7 }
count 8 { 1 3 8 }
count 9 { 1 4 6 }
count 10 { 1 4 7 }
count 11 { 1 4 8 }
count 12 { 1 6 7 }
count 13 { 1 6 8 }

...
...

count 28 { 3 6 7 }
count 29 { 3 6 8 }
count 30 { 3 7 8 }
count 31 { 4 6 7 }
count 32 { 4 6 8 }
count 33 { 4 7 8 }
count 34 { 6 7 8 }

istride 0 { 6 7 8 }
istride 1 { 6 7 8 }
istride 2 { 6 7 8 }
istride 3 { 6 7 8 }
istride 4 { 6 7 8 }
istride 5 { 6 7 8 }
istride 6 { 6 7 8 }
istride 7 { 6 7 8 }
istride 8 { 6 7 8 }
istride 9 { 6 7 8 }
istride 10 { 6 7 8 }
istride 11 { 6 7 8 }
istride 12 { 6 7 8 }

...
...

istride 30 { 6 7 8 }
istride 31 { 6 7 8 }
istride 32 { 6 7 8 }
istride 33 { 6 7 8 }
istride 34 { 6 7 8 }

如您所见,它在迭代组合的 do...while 循环中正确打印组合,但仅在后续循环中迭代 gptrarray 元素时打印按字典顺序排列的最终组合。

我做错了什么?

更新:一种可能的解决方法似乎是完全取消 glib 并手动将组合数据复制到动态分配的数组中:

  gsl_combination *c = gsl_combination_calloc (M * M, M);
long **basis;
long dim = 0;
//Evaluate the dimensionality of the Hilbert space (# of allowed combinations)
do
{
//c is the ith combination of M integers from M^2 integers
//Get all the non forbidden elements
if (is_forbidden (c) == GSL_FAILURE)
{ //If the site is NOT forbidden, append dim
dim++;
}
}
while (gsl_combination_next (c) == GSL_SUCCESS);


//Now, generate the actual basis
//basis is an array of arrays that will contain the
//selected basis vectors. Each basis vector is an array of M integers
basis = (long **) malloc (dim * sizeof (long *));
for (count = 0; count < dim; count++)
basis[count] = (long *) malloc (M * sizeof (long));

//Reset the combination to the one that is lexicographically first
gsl_combination_init_first (c);
count = 0;
//Now, append all allowed combinations to the basis
do
{
//c is the ith combination of M integers from M^2 integers
//Get all the non forbidden elements
if (is_forbidden (c) == GSL_FAILURE)
{ //If the site is NOT forbidden, append data in c to basis
for (istride = 0; istride < M; istride++)
basis[count][istride] = c->data[istride];
count++;
}
}
while (gsl_combination_next (c) == GSL_SUCCESS);

//Now, access each basis element from GArray
//basis[i] is the ith combination. jth combination element is basis[i][j]
printf (
"Printing all allowed combinations of sites in basis\n"
"---------------------------------------------------\n");


for (istride = 0; istride < dim; istride++)
{
printf ("stride # %3ld:\t{", istride);
for (count = 0; count < M; count++)
printf (" %ld", basis[istride][count]);
printf (" }\n");
}
/*Do whatever*/
...
...
free(basis);

最佳答案

反例,有效!所以证明和GPtrArray没有关系, 但 g_ptr_array_add (basis, c); //Appends c to basis您总是将最新的值添加到 ptr 数组中(但始终指向相同的对象)。因此,您可以对其进行修改,以反射(reflect)下一个要添加的内容,并在同一步骤中更改最后添加的内容。

pkg-config --modversion glib-2.0
2.37.7

使用的演示代码:

#include <glib.h>
#include <glib/gprintf.h>

int main()
{
GPtrArray *a = g_ptr_array_new ();
gpointer data = a;
int i;

for (i=0; i<10; i++, data++)
{
g_ptr_array_add (a, data);
if (i>0)
g_printf ("[%i] last: %p \n", i, g_ptr_array_index (a, i-1));
g_printf ("[%i] current: %p \n", i, g_ptr_array_index (a, i));
}

g_printf ("---- cut ----\n");


for (i=0; i<10; i++, data++)
{
g_printf ("[%i] recheck: %p \n", i, g_ptr_array_index (a, i));
}

g_ptr_array_unref (a);
return 0;
}

输出:

[0] current: 0x1c1ae00 
[1] last: 0x1c1ae00
[1] current: 0x1c1ae01
[2] last: 0x1c1ae01
[2] current: 0x1c1ae02
[3] last: 0x1c1ae02
[3] current: 0x1c1ae03
[4] last: 0x1c1ae03
[4] current: 0x1c1ae04
[5] last: 0x1c1ae04
[5] current: 0x1c1ae05
[6] last: 0x1c1ae05
[6] current: 0x1c1ae06
[7] last: 0x1c1ae06
[7] current: 0x1c1ae07
[8] last: 0x1c1ae07
[8] current: 0x1c1ae08
[9] last: 0x1c1ae08
[9] current: 0x1c1ae09
---- cut ----
[0] recheck: 0x1c1ae00
[1] recheck: 0x1c1ae01
[2] recheck: 0x1c1ae02
[3] recheck: 0x1c1ae03
[4] recheck: 0x1c1ae04
[5] recheck: 0x1c1ae05
[6] recheck: 0x1c1ae06
[7] recheck: 0x1c1ae07
[8] recheck: 0x1c1ae08
[9] recheck: 0x1c1ae09

关于c - 在 glib 中向 gprtarray 添加结构元素,但无法检索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18446662/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com