Я не очень хорош с указателями.Я знаю достаточно, чтобы заставить работать массив указателей на char, как в первом примере ниже.Но я не хочу передавать весь массив указателей, потому что он занимает слишком много места в стеке.Я хотел бы передать единственный указатель на память, выделенную для массива указателей.Я понятия не имею, как это сделать.
Эта программа работает:
#include "pch.h"
#include "$StdHdr.h"
#include "TmpTstPtr1.h"
#define SRC_LIN_SIZ 150
int main(int ArgCnt, char * ArgVal[])
{
char InpFilPth[MAX_PATH + 1];
FILE * InpFilPtr;
char ** SrcArr;
unsigned Sub1;
unsigned SrcArrCnt = 0;
strncpy_s(InpFilPth, "TmpTstPtr1.cpp", strlen("TmpTstPtr1.cpp"));
fopen_s(&InpFilPtr, InpFilPth, "r");
SrcArr = (char **)malloc(999999 * sizeof(char *));
LodSrcArr(InpFilPtr, SrcArr, &SrcArrCnt);
for (Sub1 = 0; Sub1 < SrcArrCnt; Sub1++) {
printf("SrcArr[%d] = %s\n", Sub1, SrcArr[Sub1]);
}
fclose(InpFilPtr);
return 0;
}
void LodSrcArr(FILE * InpFilPtr, char ** SrcArr, unsigned * SrcArrCnt)
{
char SrcLin[SRC_LIN_SIZ + 1];
char * GetStrPtr;
GetStrPtr = GetStr(SrcLin, SRC_LIN_SIZ, InpFilPtr);
while (GetStrPtr != NULL) {
SrcArr[*SrcArrCnt] = (char *)malloc(SRC_LIN_SIZ + 1);
// CpySiz(SrcArr[*SrcArrCnt], strlen(SrcLin) + 1, SrcLin);
errno = strncpy_s(SrcArr[*SrcArrCnt], SRC_LIN_SIZ + 1, SrcLin, strlen(SrcLin));
(*SrcArrCnt)++;
GetStrPtr = GetStr(SrcLin, SRC_LIN_SIZ, InpFilPtr);
}
}
char * GetStr(char * Str, const int MaxChr, FILE * InpFilPtr)
{
char * InpRtnVal = NULL;
unsigned Sub1;
// Get string from input file. Find the end of the string if something entered.
InpRtnVal = fgets(Str, MaxChr + 1, InpFilPtr);
if (InpRtnVal != NULL) {
Sub1 = 0;
while (Str[Sub1] != '\n' && Str[Sub1] != '\0') {
Sub1++;
}
// Replace newline with null.
if (Str[Sub1] == '\n') {
Str[Sub1] = '\0';
}
}
return InpRtnVal;
Следующая программа даже близко не подходит:
#include "pch.h"
#include "$StdHdr.h"
#include "TmpTstPtr2.h"
#define SRC_LIN_SIZ 150
int main(int ArgCnt, char * ArgVal[])
{
char InpFilPth[MAX_PATH + 1];
FILE * InpFilPtr;
char ** SrcArr;
unsigned Sub1;
unsigned SrcArrCnt = 0;
char *** SrcArrPtr = NULL;
strncpy_s(InpFilPth, "TmpTstPtr2.cpp", strlen("TmpTstPtr2.cpp"));
fopen_s(&InpFilPtr, InpFilPth, "r");
SrcArr = (char **)malloc(999999 * sizeof(char *));
SrcArrPtr = &SrcArr;
LodSrcArr(InpFilPtr, SrcArrPtr, &SrcArrCnt);
SrcArrPtr = &SrcArr;
for (Sub1 = 0; Sub1 < SrcArrCnt; Sub1++) {
// printf("SrcArr[%d] = %s\n", Sub1, SrcArr[Sub1]); // got "Exception thrown: read access violation. it was 0xCDCDCDCD."
printf("SrcArr[%d] = %s\n", Sub1, **SrcArrPtr); // get 75 lines of garbage
(**SrcArrPtr) += sizeof(char *);
}
fclose(InpFilPtr);
return 0;
}
void LodSrcArr(FILE * InpFilPtr, char *** SrcArrPtr, unsigned * SrcArrCnt)
{
char SrcLin[SRC_LIN_SIZ + 1];
char * GetStrPtr;
GetStrPtr = GetStr(SrcLin, SRC_LIN_SIZ, InpFilPtr);
// while (GetStrPtr != NULL and *SrcArrCnt == 0) {
while (GetStrPtr != NULL) {
**SrcArrPtr = (char *)malloc(SRC_LIN_SIZ + 1);
// CpySiz(SrcArr[*SrcArrCnt], strlen(SrcLin) + 1, SrcLin);
errno = strncpy_s(**SrcArrPtr, SRC_LIN_SIZ + 1, SrcLin, strlen(SrcLin));
(**SrcArrPtr) += sizeof(char *);
(*SrcArrCnt)++;
GetStrPtr = GetStr(SrcLin, SRC_LIN_SIZ, InpFilPtr);
}
}
char * GetStr(char * Str, const int MaxChr, FILE * InpFilPtr)
{
char * InpRtnVal = NULL;
unsigned Sub1;
// Get string from input file. Find the end of the string if something entered.
InpRtnVal = fgets(Str, MaxChr + 1, InpFilPtr);
if (InpRtnVal != NULL) {
Sub1 = 0;
while (Str[Sub1] != '\n' && Str[Sub1] != '\0') {
Sub1++;
}
// Replace newline with null.
if (Str[Sub1] == '\n') {
Str[Sub1] = '\0';
}
}
return InpRtnVal;
}
Как комментариискажем, когда я пытаюсь получить доступ к SrcArr
через индекс, я получаю ошибку во время выполнения.Когда я пытаюсь получить доступ через указатель, я получаю мусор.Проблема может быть там, где я говорю SrcArrPtr = &SrcArr;
.Я не знаю, насколько это важно, но напечатанный мусор на 4 символа короче с каждой последующей строкой.Как будто он на самом деле печатает сам массив указателей, а не строки, на которые они указывают.Я не знаю.
Причина, по которой я закодировал его, как указано выше, состоит в том, чтобы заставить программу компилироваться.Я никогда не пытался использовать 3 указателя раньше.Возможно ли то, что я пытаюсь сделать?Если так, может кто-нибудь показать мне, как?Объяснение того, как это работает, было бы неплохо, но не обязательно.(Я использую Visual Studio 2017, хотя не думаю, что это имеет значение.)
TIA.