有关指针和数组的问题

int GetDataSize(char *filename, int **DataSize)
{
FILE * fp, *fp_i;
int c, ndataset;
time_t st,ed;
int n, p, i, flag,ii;
char filename_i[100];

fp = fopen(filename,"r");
if(fp == NULL)
{
printf("can't open input file %s\n",filename);
exit(1);
}

ndataset = 0;
while(!feof(fp)) {
ndataset++;
fscanf(fp, "%s\n", &filename_i);
}

*DataSize = (int *)calloc( ndataset*2, sizeof(int));

ii = 0;
rewind(fp);
while(!feof(fp)) {
ii++;
fscanf(fp, "%s\n", &filename_i);

fp_i = fopen(filename_i, "r");
if(fp_i == NULL)
{
printf("can't open input file %s\n",filename_i);
exit(1);
}
printf("start getting data size of file %d: %s\n", ii, filename_i);
time(&st);
//initialization
if (ii == 1)
{
n = 0;//samples number

// find the number of samples: n
while(1)
{
int c = fgetc(fp_i);//read a character from the data file
switch(c)
{
case '\n'://the end of line
n++;
break;
// fall through,
// count the '-1' element
case EOF://file end
goto out;
default:
;
}
}

}
out:
rewind(fp_i);//Repositions the file pointer to the beginning of a file

// find number of variables: p
p= 0;
i= 0;
flag = 1;
while(1)
{
c = getc(fp_i);
if(c=='\n') goto out2;//end of line
if(isspace(c))
{
flag = 1;
}
/*do {
c = getc(fp);
if(c=='\n') goto out2;//end of line
} while(isspace(c));//space
*/
if (!isspace(c) && (flag==1))
{
p++;//indicate the dimension of the vector
flag = 0;
}

}
out2:
fclose(fp_i);

time(&ed);

// DataSize[0] = n;
(*DataSize)[ndataset * 0 + ii - 1] = n;
(*DataSize)[ndataset * 1 + ii - 1] += p-1;

}

关于(*DataSize)[ndataset * 0 + ii - 1] = n;(*DataSize)[ndataset * 1 + ii - 1] += p-1;不理解,请指教。另外一个问题是(DataSize)[ndataset * 0 + ii - 1] 去掉括号变成DataSize[ndataset * 0 + ii -1],两者之间有什么区别?

楼主您好,

(*DataSize)[…] = …;

在这个形式里,表明*DataSize本身能被当作一个指向1维数组/缓冲区的指针。
而DataSize则是一个指向 一个指向一维数组或者缓冲区的指针 的指针。。(有点绕,请仔细看)。

也就是说,从DataSize可以dereference出一个指针tmp, 而tmp则向一个一维数组(或者缓冲区)。
您可以分步看:(因为您没有给很出DataSize的具体定义,所以我使用了auto来表示自动类型推导。您需要VS 2010方可编译)
auto *p = DataSize; //请注意这里是DataSize
p[…] = …;

这是您的第一个问题。

您的第二个问题:
*DataSize[…] = …;

则表明您DataSize是一个指针数组,而DataSize指向这个富含很多指针的指针数组的首地址。您的*DataSize[…]可以拆分为:(注意auto表示自动类型推导)
auto *p = DataSize[…];
*p = …;
所以您看,它们是不同的。

(上文的auto您可以在知道DataSize的具体类型后,自行替换掉)。

好的,谢谢!

int **pMatrix = new int*[row];

 for(int i = 0; i < row; i++)
 {
   pMatrix[i]  = new int[column];

   for(int j = 0; j < column; j++)
   {
   pMatrix[i][j] = (i+j); ///////简单的初始化

   }

 }



你好,我再问关于二维数组分配的另一个问题。
这是网上的一段二维数组分配的代码,作者同时讲到“这样创建一个数组有个严重的问题,就是它的内存不连续,行与行之间的内存不连续,虽然可以用[i][j]下标访问,无法满足用指向二维数组元素型别的指针变量来访问整个数组的要求”,怎么理解?为什么呀?

作者又讲到“例如不能如下访问每个二维数组元素:

int * p = NULL;

for(p = pMatrix[0]; p < pMatrix[0]+column * row; p++)
{
int fff = *(pme);

}

”而这种访问方式对于真正的二维数组是完全可以的。出现这种原因就是因为行与行之间的内存不连续造成的。

作者又讲到“例如不能如下访问每个二维数组元素:

int * p = NULL;

for(p = pMatrix[0]; p < pMatrix[0]+column * row; p++)
{
int fff = *(pme);

}

”而这种访问方式对于真正的二维数组是完全可以的。出现这种原因就是因为行与行之间的内存不连续造成的。

LZ您好,从您的代码中可以看出,pMatrix实际上是指向一个指针数组,这个指针数组的每个元素是一个指针,并在05行指向申请到的一维数组的首地址。

由于pMatrix的每个元素是在循环中分别指向每次申请的一维数组,也就是说这些一维数组是多次申请得到的,所以并不保证前一次申请到的空间和下一次申请到的空间是连续的。

(相比之下,如果是一次性申请一个二维数组,那么空间是连续的。)

所以在这种情况下,您使用下标访问是没有问题的,和一般的二维数组无异。
但并不能通过某行的首地址+偏移量的方式,访问其他行的内容。

您提出的“指向二维数组元素型别的指针变量”估计是那种带有维度信息的指针变量,如 int (*p)[20],因为您这种方法每行之间是不保证连续的,所以您也不能用这种指针自动计算偏移量,从而访存。

(顺便说一下,上述内容均属于C语言内容,并不直接与CUDA有关。)
大致如上,供LZ参考,祝LZ好运。

没看懂这段话里面的p和pme都是干嘛的。
原文:
for(p = pMatrix[0]; p < pMatrix[0]+column * row; p++)
{
int fff = *(pme);
}
而这种访问方式对于真正的二维数组是完全可以的。

以及,没有看懂这段文字想表达什么。

如果有上下文,建议发一下。谢谢。

好的。明白了。