すみません。自分がC++素人でメモリ周り疎いのでよくあるトラブルかなと思い、動作確認できている部分は抽象的に書きました。イージーミスの可能性はかなりあります。
ソースが手元にないのですが、具体的にはこのような処理をしています。スマホから書いたので文法ミスあるかもしれません。

メイン処理
DWOR count=0;
LPBYTE pStructA = (LPBYTE)GlobalAlloc(GHND,sizeof(0));

GetPrinterInfo(pStructA,&count);//自作関数 pStructAに構造体格納

/*ここでブレーク張ってpStructAのpNameのアドレスが正しい文字列指してるのは確認済み*/
PStructB pStructB = (PStructB)GlobalAlloc(GHND,sizeof(StructB)*count);

/*ここで改めてpNameを取得しようとするとpNameのアドレスがpStructBを確保する前と変わっている。元の文字列データは以前として前のアドレス上に存在してることは確認済み。pStructA自体のアドレスは変わっていない
*/
for(i=0 ;i<count;i++){
LPTSTR name= (((PRINTER_INFO_1*)pStructA)+count)->pName;
}
〜〜〜
自作関数 (動作確認済み)
DWORD GetPrinterInfo(LPBYTE pStructA, LPDWORD count){
DWORD result=0;
DWORD pNeeded=0;
//必要サイズ取得
EnumPrinter(PRINTER_ENUM_LOCAL,NULL,1,NULL,pdw
&pNeeded,count);
//必要サイズ再確保
Global ReAlloc(pStructA,pNeeded,GHND);
//ここでPRINTER_INFO_1構造体をpStructAに格納
EnumPrinter(PRINTER_ENUM_LOCAL,NULL,1,pStructA,pdw
pNeeded,count);
return result;
}